diff --git a/lld/ELF/OutputSections.cpp b/lld/ELF/OutputSections.cpp --- a/lld/ELF/OutputSections.cpp +++ b/lld/ELF/OutputSections.cpp @@ -20,6 +20,7 @@ #include "llvm/Support/MD5.h" #include "llvm/Support/MathExtras.h" #include "llvm/Support/SHA1.h" +#include using namespace llvm; using namespace llvm::dwarf; @@ -384,18 +385,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 compiler driver may pass +// crtbegin files. +// +// Gcc uses any of crtbegin[|S|T].o. +// Clang uses Gcc's plus clang_rt.crtbegin[|S|T][-|].o. + +static bool isCrtbegin(StringRef s) { + static std::regex re(R"((clang_rt\.)?crtbegin[ST]?(-.*)?\.o)"); + s = sys::path::filename(s); + return std::regex_match(s.begin(), s.end(), re); } -static bool isCrtbegin(StringRef s) { return isCrtBeginEnd(s, "crtbegin"); } -static bool isCrtend(StringRef s) { return isCrtBeginEnd(s, "crtend"); } +static bool isCrtend(StringRef s) { + static std::regex re(R"((clang_rt\.)?crtend[ST]?(-.*)?\.o)"); + s = sys::path::filename(s); + return std::regex_match(s.begin(), s.end(), re); +} // .ctors and .dtors are sorted by this priority from highest to lowest. // diff --git a/lld/test/ELF/ctors_dtors_priority.s b/lld/test/ELF/ctors_dtors_priority.s --- a/lld/test/ELF/ctors_dtors_priority.s +++ b/lld/test/ELF/ctors_dtors_priority.s @@ -3,15 +3,27 @@ // Test .ctors* and .dtors* are sorted by priority. // RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t1 +// RUN: mkdir -p %t // RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux \ -// RUN: %p/Inputs/ctors_dtors_priority1.s -o %t-crtbegin.o +// RUN: %p/Inputs/ctors_dtors_priority1.s -o %t/crtbegin.o // RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux \ // RUN: %p/Inputs/ctors_dtors_priority2.s -o %t2 // RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux \ -// RUN: %p/Inputs/ctors_dtors_priority3.s -o %t-crtend.o -// RUN: ld.lld %t1 %t2 %t-crtend.o %t-crtbegin.o -o %t.exe +// RUN: %p/Inputs/ctors_dtors_priority3.s -o %t/crtend.o +// RUN: ld.lld %t1 %t2 %t/crtend.o %t/crtbegin.o -o %t.exe // RUN: llvm-objdump -s %t.exe | FileCheck %s +// RUN: cp %t/crtbegin.o %t/clang_rt.crtbegin.o +// RUN: cp %t/crtend.o %t/clang_rt.crtend.o +// RUN: ld.lld %t1 %t2 %t/clang_rt.crtend.o %t/clang_rt.crtbegin.o -o %t.clang_rt.exe +// RUN: llvm-objdump -s %t.clang_rt.exe | FileCheck %s + +// RUN: cp %t/crtbegin.o %t/clang_rt.crtbegin-x86_64.o +// RUN: cp %t/crtend.o %t/clang_rt.crtend-x86_64.o +// RUN: ld.lld %t1 %t2 %t/clang_rt.crtend-x86_64.o %t/clang_rt.crtbegin-x86_64.o -o %t.clang_rt-arch.exe +// RUN: llvm-objdump -s %t.clang_rt-arch.exe | FileCheck %s + + .globl _start _start: nop