Index: ELF/Config.h =================================================================== --- ELF/Config.h +++ ELF/Config.h @@ -34,6 +34,8 @@ enum class UnresolvedPolicy { NoUndef, Error, Warn, Ignore }; +enum class DiscardPolicy { Default, All, Locals, None }; + struct SymbolVersion { llvm::StringRef Name; bool IsExternCpp; @@ -79,9 +81,6 @@ bool BsymbolicFunctions; bool Demangle = true; bool DisableVerify; - bool DiscardAll; - bool DiscardLocals; - bool DiscardNone; bool EhFrameHdr; bool EnableNewDtags; bool ExportDynamic; @@ -115,6 +114,7 @@ bool ZNow; bool ZOrigin; bool ZRelro; + DiscardPolicy Discard; UnresolvedPolicy UnresolvedSymbols; BuildIdKind BuildId = BuildIdKind::None; ELFKind EKind = ELFNoneKind; Index: ELF/Driver.cpp =================================================================== --- ELF/Driver.cpp +++ ELF/Driver.cpp @@ -344,6 +344,19 @@ return false; } +static DiscardPolicy getDiscardOption(opt::InputArgList &Args) { + auto *Arg = + Args.getLastArg(OPT_discard_all, OPT_discard_locals, OPT_discard_none); + if (!Arg) + return DiscardPolicy::Default; + unsigned ID = Arg->getOption().getID(); + if (ID == OPT_discard_all) + return DiscardPolicy::All; + if (ID == OPT_discard_locals) + return DiscardPolicy::Locals; + return DiscardPolicy::None; +} + // Initializes Config members by the command line options. void LinkerDriver::readConfigs(opt::InputArgList &Args) { for (auto *Arg : Args.filtered(OPT_L)) @@ -367,9 +380,7 @@ Config->BsymbolicFunctions = Args.hasArg(OPT_Bsymbolic_functions); Config->Demangle = !Args.hasArg(OPT_no_demangle); Config->DisableVerify = Args.hasArg(OPT_disable_verify); - Config->DiscardAll = Args.hasArg(OPT_discard_all); - Config->DiscardLocals = Args.hasArg(OPT_discard_locals); - Config->DiscardNone = Args.hasArg(OPT_discard_none); + Config->Discard = getDiscardOption(Args); Config->EhFrameHdr = Args.hasArg(OPT_eh_frame_hdr); Config->EnableNewDtags = !Args.hasArg(OPT_disable_new_dtags); Config->ExportDynamic = Args.hasArg(OPT_export_dynamic); Index: ELF/OutputSections.cpp =================================================================== --- ELF/OutputSections.cpp +++ ELF/OutputSections.cpp @@ -1373,7 +1373,7 @@ // All symbols with STB_LOCAL binding precede the weak and global symbols. // .dynsym only contains global symbols. - if (!Config->DiscardAll && !StrTabSec.isDynamic()) + if (Config->Discard != DiscardPolicy::All && !StrTabSec.isDynamic()) writeLocalSymbols(Buf); writeGlobalSymbols(Buf); Index: ELF/Writer.cpp =================================================================== --- ELF/Writer.cpp +++ ELF/Writer.cpp @@ -238,7 +238,7 @@ // The main function of the writer. template void Writer::run() { - if (!Config->DiscardAll) + if (Config->Discard != DiscardPolicy::All) copyLocalSymbols(); addReservedSymbols(); @@ -327,7 +327,7 @@ if (Sec == &InputSection::Discarded) return false; - if (Config->DiscardNone) + if (Config->Discard == DiscardPolicy::None) return true; // In ELF assembly .L symbols are normally discarded by the assembler. @@ -338,7 +338,7 @@ if (!SymName.startswith(".L") && !SymName.empty()) return true; - if (Config->DiscardLocals) + if (Config->Discard == DiscardPolicy::Locals) return false; return !(Sec->getSectionHdr()->sh_flags & SHF_MERGE);