[lld] c720b16 - [ELF] Use SmallVector for SharedFile and simplify parseVerdefs
Fangrui Song via llvm-commits
llvm-commits at lists.llvm.org
Tue Dec 14 21:11:51 PST 2021
Author: Fangrui Song
Date: 2021-12-14T21:11:45-08:00
New Revision: c720b16aa56b2a3904864d5eda19f1edd301eff4
URL: https://github.com/llvm/llvm-project/commit/c720b16aa56b2a3904864d5eda19f1edd301eff4
DIFF: https://github.com/llvm/llvm-project/commit/c720b16aa56b2a3904864d5eda19f1edd301eff4.diff
LOG: [ELF] Use SmallVector for SharedFile and simplify parseVerdefs
SHT_GNU_verdef is typically small, so it's unnecessary to reserve the vector.
While here, fix a hypothetical issue when SHT_GNU_verdef has non-increasing
version indexes, which don't happen with GNU ld, gold, ld.lld's output.
My x86-64 lld executable is 256 bytes smaller.
Added:
Modified:
lld/ELF/InputFiles.cpp
lld/ELF/InputFiles.h
Removed:
################################################################################
diff --git a/lld/ELF/InputFiles.cpp b/lld/ELF/InputFiles.cpp
index 63f83a486d3c..8b1d1827e24e 100644
--- a/lld/ELF/InputFiles.cpp
+++ b/lld/ELF/InputFiles.cpp
@@ -1318,26 +1318,21 @@ unsigned SharedFile::vernauxNum;
// vector whose nth element contains a pointer to the Elf_Verdef for version
// identifier n. Version identifiers that are not definitions map to nullptr.
template <typename ELFT>
-static std::vector<const void *> parseVerdefs(const uint8_t *base,
- const typename ELFT::Shdr *sec) {
+static SmallVector<const void *, 0>
+parseVerdefs(const uint8_t *base, const typename ELFT::Shdr *sec) {
if (!sec)
return {};
- // We cannot determine the largest verdef identifier without inspecting
- // every Elf_Verdef, but both bfd and gold assign verdef identifiers
- // sequentially starting from 1, so we predict that the largest identifier
- // will be verdefCount.
- unsigned verdefCount = sec->sh_info;
- std::vector<const void *> verdefs(verdefCount + 1);
-
// Build the Verdefs array by following the chain of Elf_Verdef objects
// from the start of the .gnu.version_d section.
+ SmallVector<const void *, 0> verdefs;
const uint8_t *verdef = base + sec->sh_offset;
- for (unsigned i = 0; i != verdefCount; ++i) {
+ for (unsigned i = 0, e = sec->sh_info; i != e; ++i) {
auto *curVerdef = reinterpret_cast<const typename ELFT::Verdef *>(verdef);
verdef += curVerdef->vd_next;
unsigned verdefIndex = curVerdef->vd_ndx;
- verdefs.resize(verdefIndex + 1);
+ if (verdefIndex >= verdefs.size())
+ verdefs.resize(verdefIndex + 1);
verdefs[verdefIndex] = curVerdef;
}
return verdefs;
diff --git a/lld/ELF/InputFiles.h b/lld/ELF/InputFiles.h
index ec6f1a7ad7a2..d359a49616e2 100644
--- a/lld/ELF/InputFiles.h
+++ b/lld/ELF/InputFiles.h
@@ -368,16 +368,16 @@ class SharedFile : public ELFFileBase {
isNeeded(!config->asNeeded) {}
// This is actually a vector of Elf_Verdef pointers.
- std::vector<const void *> verdefs;
+ SmallVector<const void *, 0> verdefs;
// If the output file needs Elf_Verneed data structures for this file, this is
// a vector of Elf_Vernaux version identifiers that map onto the entries in
// Verdefs, otherwise it is empty.
- std::vector<unsigned> vernauxs;
+ SmallVector<uint32_t, 0> vernauxs;
static unsigned vernauxNum;
- std::vector<StringRef> dtNeeded;
+ SmallVector<StringRef, 0> dtNeeded;
StringRef soName;
static bool classof(const InputFile *f) { return f->kind() == SharedKind; }
@@ -389,7 +389,7 @@ class SharedFile : public ELFFileBase {
// Non-weak undefined symbols which are not yet resolved when the SO is
// parsed. Only filled for `--no-allow-shlib-undefined`.
- std::vector<Symbol *> requiredSymbols;
+ SmallVector<Symbol *, 0> requiredSymbols;
private:
template <typename ELFT>
More information about the llvm-commits
mailing list