Index: lld/ELF/OutputSections.cpp =================================================================== --- lld/ELF/OutputSections.cpp +++ lld/ELF/OutputSections.cpp @@ -6,6 +6,8 @@ // //===----------------------------------------------------------------------===// +#include + #include "OutputSections.h" #include "Config.h" #include "LinkerScript.h" @@ -384,18 +386,23 @@ flags |= SHF_INFO_LINK; } -// Returns true if S matches /Filename.?\.o$/. -static bool isCrtBeginEnd(StringRef s, StringRef filename) { - if (!s.endswith(".o")) - return false; - s = s.drop_back(2); - if (s.endswith(filename)) - return true; - return !s.empty() && s.drop_back().endswith(filename); +// Returns true if S is in one of the many forms the driver may +// pass crtbegin and crtend files. +// +// Gcc uses any of crt[begin|end][|S|T].o. +// Clang uses Gcc's plus clang_rt.crt[begin|end][|S|T][-|].o. + +static bool isCrtbegin(StringRef s) { + s = llvm::sys::path::filename(s); + std::regex re(R"(^(clang_rt.)?crtbegin[ST]?[\-.*]?\.o$)"); + return std::regex_match(s.data(), re); } -static bool isCrtbegin(StringRef s) { return isCrtBeginEnd(s, "crtbegin"); } -static bool isCrtend(StringRef s) { return isCrtBeginEnd(s, "crtend"); } +static bool isCrtend(StringRef s) { + s = llvm::sys::path::filename(s); + std::regex re(R"(^(clang_rt.)?crtend[ST]?[\-.*]?\.o$)"); + return std::regex_match(s.data(), re); +} // .ctors and .dtors are sorted by this priority from highest to lowest. //