diff options
Diffstat (limited to 'Source')
-rw-r--r-- | Source/bindexplib.cxx | 82 | ||||
-rw-r--r-- | Source/bindexplib.h | 5 | ||||
-rw-r--r-- | Source/cmMakefileTargetGenerator.cxx | 7 | ||||
-rw-r--r-- | Source/cmNinjaNormalTargetGenerator.cxx | 8 | ||||
-rw-r--r-- | Source/cmcmd.cxx | 13 |
5 files changed, 108 insertions, 7 deletions
diff --git a/Source/bindexplib.cxx b/Source/bindexplib.cxx index a107294..7e5db26 100644 --- a/Source/bindexplib.cxx +++ b/Source/bindexplib.cxx @@ -64,9 +64,12 @@ */ #include "bindexplib.h" +#include "cmSystemTools.h" #include "cmsys/Encoding.hxx" #include "cmsys/FStream.hxx" #include <iostream> +#include <sstream> +#include <vector> #include <windows.h> #ifndef IMAGE_FILE_MACHINE_ARM @@ -301,7 +304,63 @@ private: bool IsI386; }; -bool DumpFile(const char* filename, std::set<std::string>& symbols, +bool DumpFileWithLlvmNm(std::string const& nmPath, const char* filename, + std::set<std::string>& symbols, + std::set<std::string>& dataSymbols) +{ + std::string output; + // break up command line into a vector + std::vector<std::string> command; + command.push_back(nmPath); + command.push_back("--no-weak"); + command.push_back("--defined-only"); + command.push_back("--format=posix"); + command.push_back(filename); + + // run the command + int exit_code = 0; + cmSystemTools::RunSingleCommand(command, &output, &output, &exit_code, "", + cmSystemTools::OUTPUT_NONE); + + if (exit_code != 0) { + fprintf(stderr, "llvm-nm returned an error: %s\n", output.c_str()); + return false; + } + + std::istringstream ss(output); + std::string line; + while (std::getline(ss, line)) { + if (line.empty()) { // last line + continue; + } + size_t sym_end = line.find(" "); + if (sym_end == std::string::npos) { + fprintf(stderr, "Couldn't parse llvm-nm output line: %s\n", + line.c_str()); + return false; + } + if (line.size() < sym_end + 1) { + fprintf(stderr, "Couldn't parse llvm-nm output line: %s\n", + line.c_str()); + return false; + } + const std::string sym = line.substr(0, sym_end); + const char sym_type = line[sym_end + 1]; + switch (sym_type) { + case 'D': + dataSymbols.insert(sym); + break; + case 'T': + symbols.insert(sym); + break; + } + } + + return true; +} + +bool DumpFile(std::string const& nmPath, const char* filename, + std::set<std::string>& symbols, std::set<std::string>& dataSymbols) { HANDLE hFile; @@ -356,16 +415,26 @@ bool DumpFile(const char* filename, std::set<std::string>& symbols, (imageHeader->Machine == IMAGE_FILE_MACHINE_I386)); symbolDumper.DumpObjFile(); } else { - // check for /bigobj format + // check for /bigobj and llvm LTO format cmANON_OBJECT_HEADER_BIGOBJ* h = (cmANON_OBJECT_HEADER_BIGOBJ*)lpFileBase; if (h->Sig1 == 0x0 && h->Sig2 == 0xffff) { + // bigobj DumpSymbols<cmANON_OBJECT_HEADER_BIGOBJ, cmIMAGE_SYMBOL_EX> symbolDumper((cmANON_OBJECT_HEADER_BIGOBJ*)lpFileBase, symbols, dataSymbols, (h->Machine == IMAGE_FILE_MACHINE_I386)); symbolDumper.DumpObjFile(); + } else if ( + // BCexCODE - llvm bitcode + (h->Sig1 == 0x4342 && h->Sig2 == 0xDEC0) || + // 0x0B17C0DE - llvm bitcode BC wrapper + (h->Sig1 == 0x0B17 && h->Sig2 == 0xC0DE)) { + + return DumpFileWithLlvmNm(nmPath, filename, symbols, dataSymbols); + } else { - printf("unrecognized file format in '%s'\n", filename); + printf("unrecognized file format in '%s, %u'\n", filename, + imageHeader->Machine); return false; } } @@ -378,7 +447,7 @@ bool DumpFile(const char* filename, std::set<std::string>& symbols, bool bindexplib::AddObjectFile(const char* filename) { - return DumpFile(filename, this->Symbols, this->DataSymbols); + return DumpFile(NmPath, filename, this->Symbols, this->DataSymbols); } bool bindexplib::AddDefinitionFile(const char* filename) @@ -419,3 +488,8 @@ void bindexplib::WriteFile(FILE* file) fprintf(file, "\t%s\n", s.c_str()); } } + +void bindexplib::SetNmPath(std::string const& nm) +{ + NmPath = nm; +} diff --git a/Source/bindexplib.h b/Source/bindexplib.h index 3e22ac7..6c066c5 100644 --- a/Source/bindexplib.h +++ b/Source/bindexplib.h @@ -12,13 +12,16 @@ class bindexplib { public: - bindexplib() {} + bindexplib() { NmPath = "nm"; } bool AddDefinitionFile(const char* filename); bool AddObjectFile(const char* filename); void WriteFile(FILE* file); + void SetNmPath(std::string const& nm); + private: std::set<std::string> Symbols; std::set<std::string> DataSymbols; + std::string NmPath; }; #endif diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx index f99fe4e..f84ec76 100644 --- a/Source/cmMakefileTargetGenerator.cxx +++ b/Source/cmMakefileTargetGenerator.cxx @@ -15,6 +15,7 @@ #include "cmGeneratorExpression.h" #include "cmGeneratorTarget.h" #include "cmGlobalUnixMakefileGenerator3.h" +#include "cmLocalCommonGenerator.h" #include "cmLocalUnixMakefileGenerator3.h" #include "cmMakefile.h" #include "cmMakefileExecutableTargetGenerator.h" @@ -1738,6 +1739,12 @@ void cmMakefileTargetGenerator::GenDefFile( this->LocalGenerator->MaybeConvertToRelativePath( this->LocalGenerator->GetCurrentBinaryDirectory(), objlist_file), cmOutputConverter::SHELL); + const char* nm_executable = this->Makefile->GetDefinition("CMAKE_NM"); + if (nm_executable && *nm_executable) { + cmd += " --nm="; + cmd += this->LocalCommonGenerator->ConvertToOutputFormat( + nm_executable, cmOutputConverter::SHELL); + } real_link_commands.insert(real_link_commands.begin(), cmd); // create a list of obj files for the -E __create_def to read cmGeneratedFileStream fout(objlist_file); diff --git a/Source/cmNinjaNormalTargetGenerator.cxx b/Source/cmNinjaNormalTargetGenerator.cxx index 17a5527..df4d45d 100644 --- a/Source/cmNinjaNormalTargetGenerator.cxx +++ b/Source/cmNinjaNormalTargetGenerator.cxx @@ -20,6 +20,7 @@ #include "cmGlobalNinjaGenerator.h" #include "cmLinkLineComputer.h" #include "cmLinkLineDeviceComputer.h" +#include "cmLocalCommonGenerator.h" #include "cmLocalGenerator.h" #include "cmLocalNinjaGenerator.h" #include "cmMakefile.h" @@ -974,6 +975,13 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement() std::string obj_list_file = mdi->DefFile + ".objs"; cmd += this->GetLocalGenerator()->ConvertToOutputFormat( obj_list_file, cmOutputConverter::SHELL); + + const char* nm_executable = GetMakefile()->GetDefinition("CMAKE_NM"); + if (nm_executable && *nm_executable) { + cmd += " --nm="; + cmd += this->LocalCommonGenerator->ConvertToOutputFormat( + nm_executable, cmOutputConverter::SHELL); + } preLinkCmdLines.push_back(std::move(cmd)); // create a list of obj files for the -E __create_def to read diff --git a/Source/cmcmd.cxx b/Source/cmcmd.cxx index 2be8bae..08cad7d 100644 --- a/Source/cmcmd.cxx +++ b/Source/cmcmd.cxx @@ -558,8 +558,8 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string> const& args) #if defined(_WIN32) && !defined(CMAKE_BOOTSTRAP) else if (args[1] == "__create_def") { if (args.size() < 4) { - std::cerr - << "__create_def Usage: -E __create_def outfile.def objlistfile\n"; + std::cerr << "__create_def Usage: -E __create_def outfile.def " + "objlistfile [-nm=nm-path]\n"; return 1; } FILE* fout = cmsys::SystemTools::Fopen(args[2].c_str(), "w+"); @@ -576,6 +576,15 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string> const& args) } std::string file; bindexplib deffile; + if (args.size() >= 5) { + auto a = args[4]; + if (cmHasLiteralPrefix(a, "--nm=")) { + deffile.SetNmPath(a.substr(5)); + std::cerr << a.substr(5) << "\n"; + } else { + std::cerr << "unknown argument: " << a << "\n"; + } + } while (cmSystemTools::GetLineFromStream(fin, file)) { std::string const& ext = cmSystemTools::GetFilenameLastExtension(file); if (cmSystemTools::LowerCase(ext) == ".def") { |