diff options
-rw-r--r-- | lld/COFF/Config.h | 5 | ||||
-rw-r--r-- | lld/COFF/Driver.cpp | 50 | ||||
-rw-r--r-- | lld/COFF/Driver.h | 2 | ||||
-rw-r--r-- | lld/COFF/DriverUtils.cpp | 19 | ||||
-rw-r--r-- | lld/test/COFF/alternatename.test | 54 |
5 files changed, 106 insertions, 24 deletions
diff --git a/lld/COFF/Config.h b/lld/COFF/Config.h index 1e6195cb461..46db6de33f6 100644 --- a/lld/COFF/Config.h +++ b/lld/COFF/Config.h @@ -66,9 +66,12 @@ struct Configuration { StringRef ManifestUIAccess = "'false'"; StringRef ManifestFile; - // Used by /failifmismatch option. + // Used for /failifmismatch. std::map<StringRef, StringRef> MustMatch; + // Used for /alternatename. + std::vector<std::pair<StringRef, StringRef>> AlternateNames; + uint64_t ImageBase = 0x140000000; uint64_t StackReserve = 1024 * 1024; uint64_t StackCommit = 4096; diff --git a/lld/COFF/Driver.cpp b/lld/COFF/Driver.cpp index e724a8f55e4..adf682675cf 100644 --- a/lld/COFF/Driver.cpp +++ b/lld/COFF/Driver.cpp @@ -99,6 +99,11 @@ LinkerDriver::parseDirectives(StringRef S, Config->Exports.push_back(E.get()); } + // Handle /alternatename + for (auto *Arg : Args->filtered(OPT_alternatename)) + if (auto EC = parseAlternateName(Arg->getValue())) + return EC; + // Handle /failifmismatch if (auto EC = checkFailIfMismatch(Args.get())) return EC; @@ -328,6 +333,11 @@ bool LinkerDriver::link(int Argc, const char *Argv[]) { } } + // Handle /alternatename + for (auto *Arg : Args->filtered(OPT_alternatename)) + if (parseAlternateName(Arg->getValue())) + return false; + // Handle /opt for (auto *Arg : Args->filtered(OPT_opt)) { std::string S = StringRef(Arg->getValue()).lower(); @@ -471,28 +481,6 @@ bool LinkerDriver::link(int Argc, const char *Argv[]) { } } - // Add weak aliases. Weak aliases is a mechanism to give remaining - // undefined symbols final chance to be resolved successfully. - // This is symbol renaming. - for (auto *Arg : Args->filtered(OPT_alternatename)) { - // Parse a string of the form of "/alternatename:From=To". - StringRef From, To; - std::tie(From, To) = StringRef(Arg->getValue()).split('='); - if (From.empty() || To.empty()) { - llvm::errs() << "/alternatename: invalid argument: " - << Arg->getValue() << "\n"; - return false; - } - // If From is already resolved to a Defined type, do nothing. - // Otherwise, rename it to see if To can be resolved instead. - if (Symtab.find(From)) - continue; - if (auto EC = Symtab.rename(From, To)) { - llvm::errs() << EC.message() << "\n"; - return false; - } - } - // Windows specific -- Make sure we resolve all dllexported symbols. // (We don't cache the size here because Symtab.resolve() may add // new entries to Config->Exports.) @@ -515,6 +503,24 @@ bool LinkerDriver::link(int Argc, const char *Argv[]) { } Config->GCRoots.insert(Config->EntryName); + // Add weak aliases. Weak aliases is a mechanism to give remaining + // undefined symbols final chance to be resolved successfully. + // This is symbol renaming. + for (size_t I = 0; I < Config->AlternateNames.size(); ++I) { + StringRef From = Config->AlternateNames[I].first; + StringRef To = Config->AlternateNames[I].second; + // If From is already resolved to a Defined type, do nothing. + // Otherwise, rename it to see if To can be resolved instead. + if (Symtab.find(From)) + continue; + if (Config->Verbose) + llvm::outs() << "/alternatename:" << From << "=" << To << "\n"; + if (auto EC = Symtab.rename(From, To)) { + llvm::errs() << EC.message() << "\n"; + return false; + } + } + // Make sure we have resolved all symbols. if (Symtab.reportRemainingUndefines()) return false; diff --git a/lld/COFF/Driver.h b/lld/COFF/Driver.h index 1d588d8440e..f23b7cd2d0a 100644 --- a/lld/COFF/Driver.h +++ b/lld/COFF/Driver.h @@ -119,6 +119,8 @@ std::error_code parseVersion(StringRef Arg, uint32_t *Major, uint32_t *Minor); std::error_code parseSubsystem(StringRef Arg, WindowsSubsystem *Sys, uint32_t *Major, uint32_t *Minor); +std::error_code parseAlternateName(StringRef); + // Parses a string in the form of "EMBED[,=<integer>]|NO". std::error_code parseManifest(StringRef Arg); diff --git a/lld/COFF/DriverUtils.cpp b/lld/COFF/DriverUtils.cpp index 4cb10a7dbd0..05dd62fcd9b 100644 --- a/lld/COFF/DriverUtils.cpp +++ b/lld/COFF/DriverUtils.cpp @@ -154,6 +154,25 @@ std::error_code parseSubsystem(StringRef Arg, WindowsSubsystem *Sys, return std::error_code(); } +// Parse a string of the form of "<from>=<to>". +// Results are directly written to Config. +std::error_code parseAlternateName(StringRef S) { + StringRef From, To; + std::tie(From, To) = S.split('='); + if (From.empty() || To.empty()) { + llvm::errs() << "/alternatename: invalid argument: " << S << "\n"; + return make_error_code(LLDError::InvalidOption); + } + for (std::pair<StringRef, StringRef> &P : Config->AlternateNames) { + if (From == P.first) { + llvm::errs() << "/alternatename: conflicts: " << S << "\n"; + return make_error_code(LLDError::InvalidOption); + } + } + Config->AlternateNames.push_back(std::make_pair(From, To)); + return std::error_code(); +} + // Parses a string in the form of "EMBED[,=<integer>]|NO". // Results are directly written to Config. std::error_code parseManifest(StringRef Arg) { diff --git a/lld/test/COFF/alternatename.test b/lld/test/COFF/alternatename.test index 0e8a6045726..29095d94831 100644 --- a/lld/test/COFF/alternatename.test +++ b/lld/test/COFF/alternatename.test @@ -1,4 +1,56 @@ # RUN: yaml2obj < %p/Inputs/ret42.yaml > %t.obj - # RUN: lld -flavor link2 /entry:foo /subsystem:console \ # RUN: /alternatename:foo=mainCRTStartup /out:%t.exe %t.obj + +# RUN: yaml2obj < %s > %t.obj +# RUN: lld -flavor link2 /entry:foo /subsystem:console /out:%t.exe %t.obj + +--- +header: + Machine: IMAGE_FILE_MACHINE_AMD64 + Characteristics: [] +sections: + - Name: '.text$mn' + Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ] + Alignment: 16 + SectionData: B82A000000C3 + - Name: .data + Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ] + Alignment: 16 + SectionData: '' + - Name: .drectve + Characteristics: [ IMAGE_SCN_LNK_INFO, IMAGE_SCN_LNK_REMOVE ] + Alignment: 2147483648 + SectionData: 2f616c7465726e6174656e616d653a666f6f3d6d61696e4352545374617274757000 # /alternatename:foo=mainCRTStartup +symbols: + - Name: '.text$mn' + Value: 0 + SectionNumber: 1 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_STATIC + SectionDefinition: + Length: 6 + NumberOfRelocations: 0 + NumberOfLinenumbers: 0 + CheckSum: 0 + Number: 0 + - Name: .data + Value: 0 + SectionNumber: 2 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_STATIC + SectionDefinition: + Length: 0 + NumberOfRelocations: 0 + NumberOfLinenumbers: 0 + CheckSum: 0 + Number: 0 + - Name: mainCRTStartup + Value: 0 + SectionNumber: 1 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_FUNCTION + StorageClass: IMAGE_SYM_CLASS_EXTERNAL +... |