summaryrefslogtreecommitdiff
path: root/lld/ELF/OutputSections.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lld/ELF/OutputSections.cpp')
-rw-r--r--lld/ELF/OutputSections.cpp38
1 files changed, 15 insertions, 23 deletions
diff --git a/lld/ELF/OutputSections.cpp b/lld/ELF/OutputSections.cpp
index c73d6e439238..241b3ea3b418 100644
--- a/lld/ELF/OutputSections.cpp
+++ b/lld/ELF/OutputSections.cpp
@@ -12,6 +12,7 @@
#include "SymbolTable.h"
#include "SyntheticSections.h"
#include "Target.h"
+#include "lld/Common/Arrays.h"
#include "lld/Common/Memory.h"
#include "lld/Common/Strings.h"
#include "llvm/BinaryFormat/Dwarf.h"
@@ -21,8 +22,6 @@
#include "llvm/Support/Parallel.h"
#include "llvm/Support/SHA1.h"
#include "llvm/Support/TimeProfiler.h"
-#include <regex>
-#include <unordered_set>
#if LLVM_ENABLE_ZLIB
#include <zlib.h>
#endif
@@ -342,12 +341,8 @@ template <class ELFT> void OutputSection::maybeCompress() {
// Split input into 1-MiB shards.
constexpr size_t shardSize = 1 << 20;
- const size_t numShards = (size + shardSize - 1) / shardSize;
- auto shardsIn = std::make_unique<ArrayRef<uint8_t>[]>(numShards);
- for (size_t i = 0, start = 0, end; start != size; ++i, start = end) {
- end = std::min(start + shardSize, (size_t)size);
- shardsIn[i] = makeArrayRef<uint8_t>(buf.get() + start, end - start);
- }
+ auto shardsIn = split(makeArrayRef<uint8_t>(buf.get(), size), shardSize);
+ const size_t numShards = shardsIn.size();
// Compress shards and compute Alder-32 checksums. Use Z_SYNC_FLUSH for all
// shards but the last to flush the output to a byte boundary to be
@@ -471,7 +466,7 @@ static void finalizeShtGroup(OutputSection *os,
// Some group members may be combined or discarded, so we need to compute the
// new size. The content will be rewritten in InputSection::copyShtGroup.
- std::unordered_set<uint32_t> seen;
+ DenseSet<uint32_t> seen;
ArrayRef<InputSectionBase *> sections = section->file->getSections();
for (const uint32_t &idx : section->getDataAs<uint32_t>().slice(1))
if (OutputSection *osec = sections[read32(&idx)]->getOutputSection())
@@ -521,18 +516,15 @@ void OutputSection::finalize() {
// crtbegin files.
//
// Gcc uses any of crtbegin[<empty>|S|T].o.
-// Clang uses Gcc's plus clang_rt.crtbegin[<empty>|S|T][-<arch>|<empty>].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);
-}
+// Clang uses Gcc's plus clang_rt.crtbegin[-<arch>|<empty>].o.
-static bool isCrtend(StringRef s) {
- static std::regex re(R"((clang_rt\.)?crtend[ST]?(-.*)?\.o)");
+static bool isCrt(StringRef s, StringRef beginEnd) {
s = sys::path::filename(s);
- return std::regex_match(s.begin(), s.end(), re);
+ if (!s.consume_back(".o"))
+ return false;
+ if (s.consume_front("clang_rt."))
+ return s.consume_front(beginEnd);
+ return s.consume_front(beginEnd) && s.size() <= 1;
}
// .ctors and .dtors are sorted by this order:
@@ -554,12 +546,12 @@ static bool isCrtend(StringRef s) {
// are too many real-world use cases of .ctors, so we had no choice to
// support that with this rather ad-hoc semantics.
static bool compCtors(const InputSection *a, const InputSection *b) {
- bool beginA = isCrtbegin(a->file->getName());
- bool beginB = isCrtbegin(b->file->getName());
+ bool beginA = isCrt(a->file->getName(), "crtbegin");
+ bool beginB = isCrt(b->file->getName(), "crtbegin");
if (beginA != beginB)
return beginA;
- bool endA = isCrtend(a->file->getName());
- bool endB = isCrtend(b->file->getName());
+ bool endA = isCrt(a->file->getName(), "crtend");
+ bool endB = isCrt(b->file->getName(), "crtend");
if (endA != endB)
return endB;
return getPriority(a->name) > getPriority(b->name);