Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ cl.exe : $(SRCS)
link $(LFLAGS) $** $(API_LIBS) /out:cl.exe

install : cl.exe
@if not exist "$(PREFIX)" mkdir "$(PREFIX)""
@if not exist "$(PREFIX)" mkdir "$(PREFIX)"
@if not exist "$(PREFIX)\cl.exe" move cl.exe "$(PREFIX)"
@if not exist "$(PREFIX)\link.exe" mklink "$(PREFIX)\link.exe" "$(PREFIX)\cl.exe"
@if not exist "$(PREFIX)\ifx.exe" mklink "$(PREFIX)\ifx.exe" "$(PREFIX)\cl.exe"
Expand Down
3 changes: 2 additions & 1 deletion src/coff_reader_writer.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@ bool CoffReaderWriter::Open() {
return false;
}
try {
ScopedFileAccess const obtain_write(coff_file, GENERIC_ALL);
ScopedFileAccess obtain_write(coff_file, GENERIC_ALL);
obtain_write.Access();
this->pe_stream_.open(this->file_,
std::ios::in | std::ios::out | std::ios::binary);
return this->pe_stream_.is_open();
Expand Down
6 changes: 3 additions & 3 deletions src/commandline.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -178,11 +178,11 @@ std::map<std::string, std::string> ParseReport(int argc, const char** args) {
return opts;
}

bool CheckAndPrintHelp(const char** arg, int argc) {
if (argc < 2) {
bool CheckAndPrintHelp(const char** arg, bool no_args, bool is_report, bool is_relocate) {
if (no_args && (is_relocate || is_report)) {
return print_help();
}
if (strcmp(arg[1], "--help") == 0 || strcmp(arg[1], "-h") == 0) {
if (!no_args && (strcmp(arg[1], "--help") == 0 || strcmp(arg[1], "-h") == 0)) {
return print_help();
}
return false;
Expand Down
2 changes: 1 addition & 1 deletion src/commandline.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,4 @@ std::map<std::string, std::string> ParseRelocate(const char** args, int argc);
std::map<std::string, std::string> ParseReport(int argc, const char** args);

// Writes CLI help message to stdout
bool CheckAndPrintHelp(const char** arg, int argc);
bool CheckAndPrintHelp(const char** arg, bool no_args, bool is_report, bool is_relocate);
5 changes: 5 additions & 0 deletions src/ld.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,11 @@ DWORD LdInvocation::InvokeToolchain() {
} catch (const FileIOError& e) {
return ExitConditions::FILE_IO_FAILURE;
}
// If there are no arguments (or the argument is just "/?")
// just print help and return
if(this->inputs.empty() || link_run.isHelp()) {
return ToolChainInvocation::InvokeToolchain();
}

try {
link_run.makeRsp();
Expand Down
11 changes: 10 additions & 1 deletion src/linker_invocation.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,9 @@ void LinkerInvocation::ProcessTokens(const std::string &normal_token, const std:
this->piped_args_.end()) {
this->piped_args_.at(normal_token).emplace_back(token);
}
else if (normal_token == "?") {
this->is_help_ = true;
}
}


Expand Down Expand Up @@ -113,7 +116,9 @@ void LinkerInvocation::Parse() {
// /NAME
// if no /NAME
// first input file (post rc expansion)

if (this->is_help_ || this->input_files_.empty()) {
return;
}
this->processDefFile();
std::string const ext = this->is_exe_ ? ".exe" : ".dll";
if (this->output_.empty()) {
Expand Down Expand Up @@ -318,3 +323,7 @@ std::string LinkerInvocation::get_mangled_out() const {
bool LinkerInvocation::IsExeLink() const {
return this->is_exe_ || endswith(this->get_out(), ".exe");
}

bool LinkerInvocation::isHelp() const {
return this->is_help_;
}
4 changes: 3 additions & 1 deletion src/linker_invocation.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ class LinkerInvocation {
StrList get_input_files() const;
std::string get_lib_link_args() const;
bool makeRsp();
bool isHelp() const;

private:
void ProcessTokens(const std::string &normal_token, const std::string& token);
Expand All @@ -39,7 +40,8 @@ class LinkerInvocation {
StrList command_files_;
StrList input_files_;
StrList tokens_;
bool is_exe_;
bool is_exe_ = true;
bool is_help_ = false;
std::map<std::string, StrList> piped_args_ = {
{"export", {}}, {"include", {}}, {"libpath", {}},
{"ltcg", {}}, {"machine", {}}, {"nodefaultlib", {}},
Expand Down
10 changes: 6 additions & 4 deletions src/main.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,13 @@
#include <Intsafe.h>

int main(int argc, const char* argv[]) {

if (CheckAndPrintHelp(argv, argc)) {
const bool is_relocate = IsRelocate(argv[0]);
const bool is_report = IsReport(argv[0]);
const bool no_args = argc < 2;
if (CheckAndPrintHelp(argv, no_args, is_report, is_relocate)) {
return 0;
}
if (IsRelocate(argv[0])) {
if (is_relocate) {
std::map<std::string, std::string> patch_args =
ParseRelocate(argv + 1, argc - 1);
if (patch_args.empty()) {
Expand Down Expand Up @@ -90,7 +92,7 @@ int main(int argc, const char* argv[]) {
std::cerr << "Library rename failed\n";
return ExitConditions::RENAME_FAILURE;
}
} else if (IsReport(argv[0])) {
} else if (is_report) {
std::map<std::string, std::string> report_args =
ParseReport(argc - 1, argv + 1);
if (report_args.empty()) {
Expand Down
2 changes: 1 addition & 1 deletion src/utils.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -428,7 +428,7 @@ std::string stem(const std::string& file) {
}

std::string basename(const std::string& file) {
size_t const last_path = file.find_last_of('\\') + 1;
size_t const last_path = file.find_last_of("/\\") + 1;
if (last_path == std::string::npos) {
return file;
}
Expand Down
24 changes: 4 additions & 20 deletions src/winrpath.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -248,7 +248,7 @@ LibRename::LibRename(std::string p_exe, std::string coff, bool full,
/**
* Creates the line to be provided to dumpbin.exe to produce the exports of a given
* dll in the case where we do not have access to the original link line
*
*
* Produces something like `/EXPORTS <name of coff file>`
*/
std::string LibRename::ComputeDefLine() {
Expand All @@ -258,7 +258,7 @@ std::string LibRename::ComputeDefLine() {
/**
* Drives the process of running dumpbin.exe on a PE file to determine its exports
* and produce a `.def` file
*
*
* Returns the return code of the Def file computation operation
*/
bool LibRename::ComputeDefFile() {
Expand All @@ -267,44 +267,28 @@ bool LibRename::ComputeDefFile() {
if (def_res) {
return false;
}
// Need to process the produced def file because it's wrong
// Open input file
std::ifstream input_file(this->tmp_def_file);
if (!input_file.is_open()) {
std::cerr << "Error: Could not open input file " << tmp_def_file
<< '\n';
return false;
}

// Open output file
std::ofstream output_file(this->def_file);
if (!output_file.is_open()) {
std::cerr << "Error: Could not open output file " << this->def_file
<< '\n';
return false;
}

// Write the standard .def file header
// You might want to get the DLL name dynamically from the input filename or dumpbin output
output_file << "EXPORTS\n";

std::string line;
// Read until the output column titles
while (std::getline(input_file, line)) {
std::smatch search_res = regexSearch(line, R"(ordinal\s+name)");
if (!search_res.empty()) break;
std::string const res = search_res.str();
if (!res.empty()) {
break;
}
if (!regexSearch(line, R"(ordinal\s+(?:hint\s+RVA\s+)?name)").empty()) break;
}
while (std::getline(input_file, line)) {
if (line.empty()) {
continue;
}
if (line.find("Summary") !=
std::string::
npos) { // Skip header in export block if still present
if (line.find("Summary") != std::string::npos) {
break;
}
output_file << " "
Expand Down
Loading