summaryrefslogtreecommitdiffstats
path: root/llvm/tools/llvm-objcopy/llvm-objcopy.cpp
diff options
context:
space:
mode:
authorAlexander Shaposhnikov <shal1t712@gmail.com>2018-05-22 18:24:07 +0000
committerAlexander Shaposhnikov <shal1t712@gmail.com>2018-05-22 18:24:07 +0000
commit6e7814c4848e95c0df484c7d283052f7258bc147 (patch)
tree2dd519be2f733556f9f3505da14ec3c7e55959ec /llvm/tools/llvm-objcopy/llvm-objcopy.cpp
parenta6e63f176cdf2d7555938fcbb01781d29363feea (diff)
downloadbcm5719-llvm-6e7814c4848e95c0df484c7d283052f7258bc147.tar.gz
bcm5719-llvm-6e7814c4848e95c0df484c7d283052f7258bc147.zip
[llvm-objcopy] Fix the behavior of --strip-* and --keep-symbol
If one runs llvm-objcopy --strip-all --keep-symbol foo and the symbol table indeed contains the symbol "foo" then it should not be removed. Test plan: make check-all Differential revision: https://reviews.llvm.org/D47052 llvm-svn: 333008
Diffstat (limited to 'llvm/tools/llvm-objcopy/llvm-objcopy.cpp')
-rw-r--r--llvm/tools/llvm-objcopy/llvm-objcopy.cpp107
1 files changed, 62 insertions, 45 deletions
diff --git a/llvm/tools/llvm-objcopy/llvm-objcopy.cpp b/llvm/tools/llvm-objcopy/llvm-objcopy.cpp
index 99cc1039f7d..dbe8f8c10ac 100644
--- a/llvm/tools/llvm-objcopy/llvm-objcopy.cpp
+++ b/llvm/tools/llvm-objcopy/llvm-objcopy.cpp
@@ -222,6 +222,55 @@ void HandleArgs(const CopyConfig &Config, Object &Obj, const Reader &Reader,
if (!Config.SplitDWO.empty()) {
SplitDWOToFile(Config, Reader, Config.SplitDWO, OutputElfType);
}
+
+ // TODO: update or remove symbols only if there is an option that affects them.
+ if (Obj.SymbolTable) {
+ Obj.SymbolTable->updateSymbols([&](Symbol &Sym) {
+ if ((Config.LocalizeHidden &&
+ (Sym.Visibility == STV_HIDDEN || Sym.Visibility == STV_INTERNAL)) ||
+ (!Config.SymbolsToLocalize.empty() &&
+ is_contained(Config.SymbolsToLocalize, Sym.Name)))
+ Sym.Binding = STB_LOCAL;
+
+ if (!Config.SymbolsToGlobalize.empty() &&
+ is_contained(Config.SymbolsToGlobalize, Sym.Name))
+ Sym.Binding = STB_GLOBAL;
+
+ if (!Config.SymbolsToWeaken.empty() &&
+ 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();
+ });
+
+ Obj.removeSymbols([&](const Symbol &Sym) {
+ if (!Config.SymbolsToKeep.empty() &&
+ is_contained(Config.SymbolsToKeep, Sym.Name))
+ return false;
+
+ if (Config.DiscardAll && 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.SymbolsToRemove.empty() &&
+ is_contained(Config.SymbolsToRemove, Sym.Name)) {
+ return true;
+ }
+
+ return false;
+ });
+ }
SectionPred RemovePred = [](const SectionBase &) { return false; };
@@ -327,6 +376,19 @@ void HandleArgs(const CopyConfig &Config, Object &Obj, const Reader &Reader,
};
}
+ // This has to be the last predicate assignment.
+ // If the option --keep-symbol has been specified
+ // and at least one of those symbols is present
+ // (equivalently, the updated symbol table is not empty)
+ // the symbol table and the string table should not be removed.
+ if (!Config.SymbolsToKeep.empty() && !Obj.SymbolTable->empty()) {
+ RemovePred = [&Obj, RemovePred](const SectionBase &Sec) {
+ if (&Sec == Obj.SymbolTable || &Sec == Obj.SymbolTable->getStrTab())
+ return false;
+ return RemovePred(Sec);
+ };
+ }
+
Obj.removeSections(RemovePred);
if (!Config.AddSection.empty()) {
@@ -347,51 +409,6 @@ void HandleArgs(const CopyConfig &Config, Object &Obj, const Reader &Reader,
if (!Config.AddGnuDebugLink.empty())
Obj.addSection<GnuDebugLinkSection>(Config.AddGnuDebugLink);
-
- if (Obj.SymbolTable) {
- Obj.SymbolTable->updateSymbols([&](Symbol &Sym) {
- if ((Config.LocalizeHidden &&
- (Sym.Visibility == STV_HIDDEN || Sym.Visibility == STV_INTERNAL)) ||
- (!Config.SymbolsToLocalize.empty() &&
- is_contained(Config.SymbolsToLocalize, Sym.Name)))
- Sym.Binding = STB_LOCAL;
-
- if (!Config.SymbolsToGlobalize.empty() &&
- is_contained(Config.SymbolsToGlobalize, Sym.Name))
- Sym.Binding = STB_GLOBAL;
-
- if (!Config.SymbolsToWeaken.empty() &&
- 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();
- });
-
- Obj.removeSymbols([&](const Symbol &Sym) {
- if (!Config.SymbolsToKeep.empty() &&
- is_contained(Config.SymbolsToKeep, Sym.Name))
- return false;
-
- if (Config.DiscardAll && Sym.Binding == STB_LOCAL &&
- Sym.getShndx() != SHN_UNDEF && Sym.Type != STT_FILE &&
- Sym.Type != STT_SECTION)
- return true;
-
- if (!Config.SymbolsToRemove.empty() &&
- is_contained(Config.SymbolsToRemove, Sym.Name)) {
- return true;
- }
-
- return false;
- });
- }
}
std::unique_ptr<Reader> CreateReader(StringRef InputFilename,
OpenPOWER on IntegriCloud