[llvm-objcopy] Allow the visibility of symbols created by --binary and
--add-symbol to be specified with --new-symbol-visibility

llvm-svn: 370458
diff --git a/llvm/tools/llvm-objcopy/CopyConfig.cpp b/llvm/tools/llvm-objcopy/CopyConfig.cpp
index 2c1dab9..9591e5a 100644
--- a/llvm/tools/llvm-objcopy/CopyConfig.cpp
+++ b/llvm/tools/llvm-objcopy/CopyConfig.cpp
@@ -177,7 +177,8 @@
   return SFU;
 }
 
-static Expected<NewSymbolInfo> parseNewSymbolInfo(StringRef FlagValue) {
+static Expected<NewSymbolInfo> parseNewSymbolInfo(StringRef FlagValue,
+                                                  uint8_t DefaultVisibility) {
   // Parse value given with --add-symbol option and create the
   // new symbol if possible. The value format for --add-symbol is:
   //
@@ -222,6 +223,8 @@
     return createStringError(errc::invalid_argument, "bad symbol value: '%s'",
                              Flags[0].str().c_str());
 
+  SI.Visibility = DefaultVisibility;
+
   using Functor = std::function<void(void)>;
   SmallVector<StringRef, 6> UnsupportedFlags;
   for (size_t I = 1, NumFlags = Flags.size(); I < NumFlags; ++I)
@@ -488,6 +491,21 @@
     Config.BinaryArch = *MI;
   }
 
+  if (opt::Arg *A = InputArgs.getLastArg(OBJCOPY_new_symbol_visibility)) {
+    const uint8_t Invalid = 0xff;
+    Config.NewSymbolVisibility = StringSwitch<uint8_t>(A->getValue())
+                                     .Case("default", ELF::STV_DEFAULT)
+                                     .Case("hidden", ELF::STV_HIDDEN)
+                                     .Case("internal", ELF::STV_INTERNAL)
+                                     .Case("protected", ELF::STV_PROTECTED)
+                                     .Default(Invalid);
+
+    if (Config.NewSymbolVisibility == Invalid)
+      return createStringError(
+          errc::invalid_argument, "'%s' is not a valid symbol visibility",
+          InputArgs.getLastArgValue(OBJCOPY_new_symbol_visibility).str().c_str());
+  }
+
   Config.OutputFormat = StringSwitch<FileFormat>(OutputFormat)
                             .Case("binary", FileFormat::Binary)
                             .Case("ihex", FileFormat::IHex)
@@ -696,7 +714,9 @@
                                      Arg->getValue(), UseRegex))
       return std::move(E);
   for (auto Arg : InputArgs.filtered(OBJCOPY_add_symbol)) {
-    Expected<NewSymbolInfo> NSI = parseNewSymbolInfo(Arg->getValue());
+    Expected<NewSymbolInfo> NSI = parseNewSymbolInfo(
+        Arg->getValue(),
+        Config.NewSymbolVisibility.getValueOr(ELF::STV_DEFAULT));
     if (!NSI)
       return NSI.takeError();
     Config.SymbolsToAdd.push_back(*NSI);