https://github.com/c-rhodes updated https://github.com/llvm/llvm-project/pull/198665
>From 4d5dffb59420df29cc3b419a7fc90834aed7f7a9 Mon Sep 17 00:00:00 2001 From: Fangrui Song <[email protected]> Date: Sat, 16 May 2026 14:38:18 -0700 Subject: [PATCH] [ELF] Initialize Symbol fields in the constructor instead of via memset (#198129) `initSectionsAndLocalSyms` and `makeDefined` memset the storage to zero and then placement-new a Symbol-derived object into it. Placement new begins a new object's lifetime. The standard does not seem to guarantee the memset bytes carry into members the constructor leaves uninitialized. lld built by GCC 16 can make Valgrind report reads of Symbol::flags (via getSymSectionIndex during finalizeSections) as uses of uninitialized values (ClangBuiltLinux/linux#2162). This patch reinstates the per-field initialization that commit 778742760534 ("[ELF] Avoid redundant assignment to Symbol fields. NFC") had replaced with a bulk memset. (cherry picked from commit 905a88b923433eb8cd83677ea55bee82eb9ba498) --- lld/ELF/InputFiles.cpp | 2 -- lld/ELF/Symbols.h | 20 ++++++++++++-------- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/lld/ELF/InputFiles.cpp b/lld/ELF/InputFiles.cpp index 176f6937a8d66..7ba2be5d1608f 100644 --- a/lld/ELF/InputFiles.cpp +++ b/lld/ELF/InputFiles.cpp @@ -1261,7 +1261,6 @@ void ObjFile<ELFT>::initSectionsAndLocalSyms(bool ignoreComdats) { if (!firstGlobal) return; SymbolUnion *locals = makeThreadLocalN<SymbolUnion>(firstGlobal); - memset(locals, 0, sizeof(SymbolUnion) * firstGlobal); ArrayRef<Elf_Sym> eSyms = this->getELFSyms<ELFT>(); for (size_t i = 0, end = firstGlobal; i != end; ++i) { @@ -1297,7 +1296,6 @@ void ObjFile<ELFT>::initSectionsAndLocalSyms(bool ignoreComdats) { else new (symbols[i]) Defined(ctx, this, name, STB_LOCAL, eSym.st_other, type, eSym.st_value, eSym.st_size, sec); - symbols[i]->partition = 1; symbols[i]->isUsedInRegularObj = true; } } diff --git a/lld/ELF/Symbols.h b/lld/ELF/Symbols.h index 034c8734addb8..23994ccea1ef0 100644 --- a/lld/ELF/Symbols.h +++ b/lld/ELF/Symbols.h @@ -102,7 +102,7 @@ class Symbol { uint8_t symbolKind; // The partition whose dynamic symbol table contains this symbol's definition. - uint8_t partition; + uint8_t partition = 1; // True if this symbol is preemptible at load time. // @@ -242,8 +242,13 @@ class Symbol { Symbol(Kind k, InputFile *file, StringRef name, uint8_t binding, uint8_t stOther, uint8_t type) : file(file), nameData(name.data()), nameSize(name.size()), type(type), - binding(binding), stOther(stOther), symbolKind(k), ltoCanOmit(false), - archSpecificBit(false) {} + binding(binding), stOther(stOther), symbolKind(k), isPreemptible(false), + isUsedInRegularObj(false), isExported(false), ltoCanOmit(false), + traced(false), hasVersionSuffix(false), isInIplt(false), + gotInIgot(false), folded(false), archSpecificBit(false), + scriptDefined(false), dsoDefined(false), dsoProtected(false), + versionScriptAssigned(false), thunkAccessed(false), + inDynamicList(false), referenced(false), referencedAfterWrap(false) {} void overwrite(Symbol &sym, Kind k) const { if (sym.traced) @@ -302,12 +307,12 @@ class Symbol { // Temporary flags used to communicate which symbol entries need PLT and GOT // entries during postScanRelocations(); - std::atomic<uint16_t> flags; + std::atomic<uint16_t> flags = 0; // A ctx.symAux index used to access GOT/PLT entry indexes. This is allocated // in postScanRelocations(). - uint32_t auxIdx; - uint32_t dynsymIndex; + uint32_t auxIdx = 0; + uint32_t dynsymIndex = 0; // If `file` is SharedFile (for SharedSymbol or copy-relocated Defined), this // represents the Verdef index within the input DSO, which will be converted @@ -315,7 +320,7 @@ class Symbol { // index (VER_NDX_LOCAL, VER_NDX_GLOBAL, or a named version). // VER_NDX_LOCAL indicates a defined symbol that has been localized by a // version script's local: directive or --exclude-libs. - uint16_t versionId; + uint16_t versionId = 0; LLVM_PREFERRED_TYPE(bool) uint8_t versionScriptAssigned : 1; @@ -526,7 +531,6 @@ union SymbolUnion { template <typename... T> Defined *makeDefined(T &&...args) { auto *sym = getSpecificAllocSingleton<SymbolUnion>().Allocate(); - memset(sym, 0, sizeof(Symbol)); auto &s = *new (reinterpret_cast<Defined *>(sym)) Defined(std::forward<T>(args)...); return &s; } _______________________________________________ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
