[llvm] r356889 - [llvm-objcopy] - Refactor the code. NFC.
George Rimar via llvm-commits
llvm-commits at lists.llvm.org
Mon Mar 25 05:34:25 PDT 2019
Author: grimar
Date: Mon Mar 25 05:34:25 2019
New Revision: 356889
URL: http://llvm.org/viewvc/llvm-project?rev=356889&view=rev
Log:
[llvm-objcopy] - Refactor the code. NFC.
The idea of the patch is about to move out the code to a new
helper static functions (to reduce the size of 'handleArgs' and to
isolate the parts of it's logic).
Differential revision: https://reviews.llvm.org/D59762
Modified:
llvm/trunk/tools/llvm-objcopy/ELF/ELFObjcopy.cpp
Modified: llvm/trunk/tools/llvm-objcopy/ELF/ELFObjcopy.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-objcopy/ELF/ELFObjcopy.cpp?rev=356889&r1=356888&r2=356889&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-objcopy/ELF/ELFObjcopy.cpp (original)
+++ llvm/trunk/tools/llvm-objcopy/ELF/ELFObjcopy.cpp Mon Mar 25 05:34:25 2019
@@ -298,110 +298,94 @@ static bool isUnneededSymbol(const Symbo
Sym.Type != STT_FILE && Sym.Type != STT_SECTION;
}
-// This function handles the high level operations of GNU objcopy including
-// handling command line options. It's important to outline certain properties
-// we expect to hold of the command line operations. Any operation that "keeps"
-// should keep regardless of a remove. Additionally any removal should respect
-// any previous removals. Lastly whether or not something is removed shouldn't
-// depend a) on the order the options occur in or b) on some opaque priority
-// system. The only priority is that keeps/copies overrule removes.
-static Error handleArgs(const CopyConfig &Config, Object &Obj,
- const Reader &Reader, ElfType OutputElfType) {
+static Error updateAndRemoveSymbols(const CopyConfig &Config, Object &Obj) {
+ // TODO: update or remove symbols only if there is an option that affects
+ // them.
+ if (!Obj.SymbolTable)
+ return Error::success();
- if (!Config.SplitDWO.empty())
- if (Error E =
- splitDWOToFile(Config, Reader, Config.SplitDWO, OutputElfType))
- return E;
+ Obj.SymbolTable->updateSymbols([&](Symbol &Sym) {
+ // Common and undefined symbols don't make sense as local symbols, and can
+ // even cause crashes if we localize those, so skip them.
+ if (!Sym.isCommon() && Sym.getShndx() != SHN_UNDEF &&
+ ((Config.LocalizeHidden &&
+ (Sym.Visibility == STV_HIDDEN || Sym.Visibility == STV_INTERNAL)) ||
+ is_contained(Config.SymbolsToLocalize, Sym.Name)))
+ Sym.Binding = STB_LOCAL;
+
+ // Note: these two globalize flags have very similar names but different
+ // meanings:
+ //
+ // --globalize-symbol: promote a symbol to global
+ // --keep-global-symbol: all symbols except for these should be made local
+ //
+ // If --globalize-symbol is specified for a given symbol, it will be
+ // global in the output file even if it is not included via
+ // --keep-global-symbol. Because of that, make sure to check
+ // --globalize-symbol second.
+ if (!Config.SymbolsToKeepGlobal.empty() &&
+ !is_contained(Config.SymbolsToKeepGlobal, Sym.Name) &&
+ Sym.getShndx() != SHN_UNDEF)
+ Sym.Binding = STB_LOCAL;
+
+ if (is_contained(Config.SymbolsToGlobalize, Sym.Name) &&
+ Sym.getShndx() != SHN_UNDEF)
+ Sym.Binding = STB_GLOBAL;
+
+ if (is_contained(Config.SymbolsToWeaken, Sym.Name) &&
+ Sym.Binding == STB_GLOBAL)
+ Sym.Binding = STB_WEAK;
+
+ if (Config.Weaken && Sym.Binding == STB_GLOBAL &&
+ Sym.getShndx() != SHN_UNDEF)
+ Sym.Binding = STB_WEAK;
+
+ const auto I = Config.SymbolsToRename.find(Sym.Name);
+ if (I != Config.SymbolsToRename.end())
+ Sym.Name = I->getValue();
+
+ if (!Config.SymbolsPrefix.empty() && Sym.Type != STT_SECTION)
+ Sym.Name = (Config.SymbolsPrefix + Sym.Name).str();
+ });
+
+ // The purpose of this loop is to mark symbols referenced by sections
+ // (like GroupSection or RelocationSection). This way, we know which
+ // symbols are still 'needed' and which are not.
+ if (Config.StripUnneeded || !Config.UnneededSymbolsToRemove.empty()) {
+ for (auto &Section : Obj.sections())
+ Section.markSymbols();
+ }
+
+ auto RemoveSymbolsPred = [&](const Symbol &Sym) {
+ if (is_contained(Config.SymbolsToKeep, Sym.Name) ||
+ (Config.KeepFileSymbols && Sym.Type == STT_FILE))
+ return false;
- if (Config.OutputArch) {
- Obj.Machine = Config.OutputArch.getValue().EMachine;
- Obj.OSABI = Config.OutputArch.getValue().OSABI;
- }
+ if ((Config.DiscardMode == DiscardType::All ||
+ (Config.DiscardMode == DiscardType::Locals &&
+ StringRef(Sym.Name).startswith(".L"))) &&
+ Sym.Binding == STB_LOCAL && Sym.getShndx() != SHN_UNDEF &&
+ Sym.Type != STT_FILE && Sym.Type != STT_SECTION)
+ return true;
- // TODO: update or remove symbols only if there is an option that affects
- // them.
- if (Obj.SymbolTable) {
- Obj.SymbolTable->updateSymbols([&](Symbol &Sym) {
- // Common and undefined symbols don't make sense as local symbols, and can
- // even cause crashes if we localize those, so skip them.
- if (!Sym.isCommon() && Sym.getShndx() != SHN_UNDEF &&
- ((Config.LocalizeHidden &&
- (Sym.Visibility == STV_HIDDEN || Sym.Visibility == STV_INTERNAL)) ||
- is_contained(Config.SymbolsToLocalize, Sym.Name)))
- Sym.Binding = STB_LOCAL;
-
- // Note: these two globalize flags have very similar names but different
- // meanings:
- //
- // --globalize-symbol: promote a symbol to global
- // --keep-global-symbol: all symbols except for these should be made local
- //
- // If --globalize-symbol is specified for a given symbol, it will be
- // global in the output file even if it is not included via
- // --keep-global-symbol. Because of that, make sure to check
- // --globalize-symbol second.
- if (!Config.SymbolsToKeepGlobal.empty() &&
- !is_contained(Config.SymbolsToKeepGlobal, Sym.Name) &&
- Sym.getShndx() != SHN_UNDEF)
- Sym.Binding = STB_LOCAL;
-
- if (is_contained(Config.SymbolsToGlobalize, Sym.Name) &&
- Sym.getShndx() != SHN_UNDEF)
- Sym.Binding = STB_GLOBAL;
-
- if (is_contained(Config.SymbolsToWeaken, Sym.Name) &&
- Sym.Binding == STB_GLOBAL)
- Sym.Binding = STB_WEAK;
-
- if (Config.Weaken && Sym.Binding == STB_GLOBAL &&
- Sym.getShndx() != SHN_UNDEF)
- Sym.Binding = STB_WEAK;
-
- const auto I = Config.SymbolsToRename.find(Sym.Name);
- if (I != Config.SymbolsToRename.end())
- Sym.Name = I->getValue();
-
- if (!Config.SymbolsPrefix.empty() && Sym.Type != STT_SECTION)
- Sym.Name = (Config.SymbolsPrefix + Sym.Name).str();
- });
-
- // The purpose of this loop is to mark symbols referenced by sections
- // (like GroupSection or RelocationSection). This way, we know which
- // symbols are still 'needed' and which are not.
- if (Config.StripUnneeded || !Config.UnneededSymbolsToRemove.empty()) {
- for (auto &Section : Obj.sections())
- Section.markSymbols();
- }
-
- auto RemoveSymbolsPred = [&](const Symbol &Sym) {
- if (is_contained(Config.SymbolsToKeep, Sym.Name) ||
- (Config.KeepFileSymbols && Sym.Type == STT_FILE))
- return false;
-
- if ((Config.DiscardMode == DiscardType::All ||
- (Config.DiscardMode == DiscardType::Locals &&
- StringRef(Sym.Name).startswith(".L"))) &&
- Sym.Binding == STB_LOCAL && Sym.getShndx() != SHN_UNDEF &&
- Sym.Type != STT_FILE && Sym.Type != STT_SECTION)
- return true;
+ if (Config.StripAll || Config.StripAllGNU)
+ return true;
- if (Config.StripAll || Config.StripAllGNU)
- return true;
+ if (is_contained(Config.SymbolsToRemove, Sym.Name))
+ return true;
- if (is_contained(Config.SymbolsToRemove, Sym.Name))
- return true;
+ if ((Config.StripUnneeded ||
+ is_contained(Config.UnneededSymbolsToRemove, Sym.Name)) &&
+ isUnneededSymbol(Sym))
+ return true;
- if ((Config.StripUnneeded ||
- is_contained(Config.UnneededSymbolsToRemove, Sym.Name)) &&
- isUnneededSymbol(Sym))
- return true;
+ return false;
+ };
- return false;
- };
- if (Error E = Obj.removeSymbols(RemoveSymbolsPred))
- return E;
- }
+ return Obj.removeSymbols(RemoveSymbolsPred);
+}
+static Error replaceAndRemoveSections(const CopyConfig &Config, Object &Obj) {
SectionPred RemovePred = [](const SectionBase &) { return false; };
// Removes:
@@ -535,7 +519,33 @@ static Error handleArgs(const CopyConfig
return &Obj.addSection<DecompressedSection>(*CS);
});
- if (Error E = Obj.removeSections(RemovePred))
+ return Obj.removeSections(RemovePred);
+}
+
+// This function handles the high level operations of GNU objcopy including
+// handling command line options. It's important to outline certain properties
+// we expect to hold of the command line operations. Any operation that "keeps"
+// should keep regardless of a remove. Additionally any removal should respect
+// any previous removals. Lastly whether or not something is removed shouldn't
+// depend a) on the order the options occur in or b) on some opaque priority
+// system. The only priority is that keeps/copies overrule removes.
+static Error handleArgs(const CopyConfig &Config, Object &Obj,
+ const Reader &Reader, ElfType OutputElfType) {
+
+ if (!Config.SplitDWO.empty())
+ if (Error E =
+ splitDWOToFile(Config, Reader, Config.SplitDWO, OutputElfType))
+ return E;
+
+ if (Config.OutputArch) {
+ Obj.Machine = Config.OutputArch.getValue().EMachine;
+ Obj.OSABI = Config.OutputArch.getValue().OSABI;
+ }
+
+ if (Error E = updateAndRemoveSymbols(Config, Obj))
+ return E;
+
+ if (Error E = replaceAndRemoveSections(Config, Obj))
return E;
if (!Config.SectionsToRename.empty()) {
More information about the llvm-commits
mailing list