Index: ELF/Relocations.cpp =================================================================== --- ELF/Relocations.cpp +++ ELF/Relocations.cpp @@ -149,7 +149,7 @@ InputSectionBase &C, uint64_t Offset, int64_t Addend, RelExpr Expr) { // The Dynamic TLS Module Index Relocation for a symbol defined in an - // executable is always 1. If the target Symbol is not preemtible then + // executable is always 1. If the target Symbol is not preemptible then // we know the offset into the TLS block at static link time. bool NeedDynId = Body.isPreemptible() || Config->Shared; bool NeedDynOff = Body.isPreemptible(); @@ -527,6 +527,7 @@ // interpose any aliases. for (SharedSymbol *Sym : getSymbolsAt(SS)) { Sym->CopyRelSec = Sec; + Sym->IsPreemptible = false; Sym->CopyRelSecOff = Off; Sym->symbol()->IsUsedInRegularObj = true; } @@ -612,6 +613,7 @@ // plt. That is identified by special relocation types (R_X86_64_JUMP_SLOT, // R_386_JMP_SLOT, etc). Body.NeedsPltAddr = true; + Body.IsPreemptible = false; return toPlt(Expr); } Index: ELF/Symbols.h =================================================================== --- ELF/Symbols.h +++ ELF/Symbols.h @@ -70,7 +70,8 @@ } bool isLocal() const { return IsLocal; } InputFile *getFile() const; - bool isPreemptible() const; + bool isPreemptible() const { return IsPreemptible; } + bool computeIsPreemptible() const; StringRef getName() const { return Name; } uint8_t getVisibility() const { return StOther & 0x3; } void parseSymbolVersion(); @@ -121,6 +122,8 @@ // True if this symbol is in the Igot sub-section of the .got.plt or .got. unsigned IsInIgot : 1; + unsigned IsPreemptible : 1; + // The following fields have the same meaning as the ELF symbol attributes. uint8_t Type; // symbol type uint8_t StOther; // st_other field value Index: ELF/Symbols.cpp =================================================================== --- ELF/Symbols.cpp +++ ELF/Symbols.cpp @@ -127,7 +127,8 @@ uint8_t Type) : SymbolKind(K), NeedsPltAddr(false), IsLocal(IsLocal), IsInGlobalMipsGot(false), Is32BitMipsGot(false), IsInIplt(false), - IsInIgot(false), Type(Type), StOther(StOther), Name(Name) {} + IsInIgot(false), IsPreemptible(false), Type(Type), StOther(StOther), + Name(Name) {} InputFile *SymbolBody::getFile() const { if (isLocal()) @@ -137,10 +138,8 @@ // Returns true if a symbol can be replaced at load-time by a symbol // with the same name defined in other ELF executable or DSO. -bool SymbolBody::isPreemptible() const { - if (isLocal()) - return false; - +bool SymbolBody::computeIsPreemptible() const { + assert(!isLocal()); // Shared symbols resolve to the definition in the DSO. The exceptions are // symbols with copy relocations (which resolve to .bss) or preempt plt // entries (which resolve to that plt entry). Index: ELF/Writer.cpp =================================================================== --- ELF/Writer.cpp +++ ELF/Writer.cpp @@ -1182,6 +1182,9 @@ applySynthetic({In::EhFrame}, [](SyntheticSection *SS) { SS->finalizeContents(); }); + for (Symbol *S : Symtab->getSymbols()) + S->body()->IsPreemptible = S->body()->computeIsPreemptible(); + // Scan relocations. This must be done after every symbol is declared so that // we can correctly decide if a dynamic relocation is needed. forEachRelSec(scanRelocations);