[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 commit7787427605("[ELF] Avoid redundant assignment to Symbol fields. NFC") had replaced with a bulk memset. (cherry picked from commit905a88b923)
This commit is contained in:
parent
823afe0461
commit
4d5dffb594
2 changed files with 12 additions and 10 deletions
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -102,7 +102,7 @@ public:
|
|||
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 @@ protected:
|
|||
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 @@ public:
|
|||
|
||||
// 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 @@ public:
|
|||
// 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;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue