[llvm] [llvm-objcopy] Add llvm-objcopy option --set-symbol-visibility (PR #80872)

Ilia Kuklin via llvm-commits llvm-commits at lists.llvm.org
Tue Feb 20 09:21:11 PST 2024


https://github.com/kuilpd updated https://github.com/llvm/llvm-project/pull/80872

>From af5f188a7c4d16f1c9d7c2d8d4785d5a24e9ef00 Mon Sep 17 00:00:00 2001
From: Ilia Kuklin <ikuklin at accesssoftek.com>
Date: Tue, 6 Feb 2024 20:59:40 +0500
Subject: [PATCH 01/24] Add llvm-objcopy option --set-visibility-sym

---
 llvm/include/llvm/ObjCopy/ELF/ELFConfig.h     |   4 +
 llvm/lib/ObjCopy/ELF/ELFObjcopy.cpp           |   3 +
 .../llvm-objcopy/ELF/set-visibility.test      | 139 ++++++++++++++++++
 llvm/tools/llvm-objcopy/ObjcopyOptions.cpp    |  43 ++++++
 llvm/tools/llvm-objcopy/ObjcopyOpts.td        |  11 ++
 5 files changed, 200 insertions(+)
 create mode 100644 llvm/test/tools/llvm-objcopy/ELF/set-visibility.test

diff --git a/llvm/include/llvm/ObjCopy/ELF/ELFConfig.h b/llvm/include/llvm/ObjCopy/ELF/ELFConfig.h
index d77cb69b159db6..b3efa3205e3766 100644
--- a/llvm/include/llvm/ObjCopy/ELF/ELFConfig.h
+++ b/llvm/include/llvm/ObjCopy/ELF/ELFConfig.h
@@ -9,6 +9,7 @@
 #ifndef LLVM_OBJCOPY_ELF_ELFCONFIG_H
 #define LLVM_OBJCOPY_ELF_ELFCONFIG_H
 
+#include "llvm/ObjCopy/CommonConfig.h"
 #include "llvm/Object/ELFTypes.h"
 
 namespace llvm {
@@ -18,6 +19,9 @@ namespace objcopy {
 struct ELFConfig {
   uint8_t NewSymbolVisibility = (uint8_t)ELF::STV_DEFAULT;
 
+  NameMatcher SymbolsToSetVisibility;
+  uint8_t SetVisibilityType = ELF::STV_DEFAULT;
+
   // ELF entry point address expression. The input parameter is an entry point
   // address in the input ELF file. The entry address in the output file is
   // calculated with EntryExpr(input_address), when either --set-start or
diff --git a/llvm/lib/ObjCopy/ELF/ELFObjcopy.cpp b/llvm/lib/ObjCopy/ELF/ELFObjcopy.cpp
index b6d77d17bae36c..b768b7c5d05d7b 100644
--- a/llvm/lib/ObjCopy/ELF/ELFObjcopy.cpp
+++ b/llvm/lib/ObjCopy/ELF/ELFObjcopy.cpp
@@ -290,6 +290,9 @@ static Error updateAndRemoveSymbols(const CommonConfig &Config,
     return Error::success();
 
   Obj.SymbolTable->updateSymbols([&](Symbol &Sym) {
+    if (ELFConfig.SymbolsToSetVisibility.matches(Sym.Name) &&
+        Sym.getShndx() != SHN_UNDEF)
+      Sym.Visibility = ELFConfig.SetVisibilityType;
     // 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 &&
diff --git a/llvm/test/tools/llvm-objcopy/ELF/set-visibility.test b/llvm/test/tools/llvm-objcopy/ELF/set-visibility.test
new file mode 100644
index 00000000000000..bc1c92021c4fe3
--- /dev/null
+++ b/llvm/test/tools/llvm-objcopy/ELF/set-visibility.test
@@ -0,0 +1,139 @@
+
+# RUN: yaml2obj %s -o %t.o
+# RUN: echo '.*' > %t.symbols.regex
+
+# RUN: cp %t.o %t0.o
+# RUN: llvm-objcopy %t0.o --set-visibility-syms=%t.symbols.regex=default --regex
+# RUN: llvm-readelf -s %t0.o | FileCheck %s --check-prefix=DEF
+# DEF-DAG: LOCAL  DEFAULT     1 default_local
+# DEF-DAG: LOCAL  DEFAULT     1 internal_local
+# DEF-DAG: LOCAL  DEFAULT     1 hidden_local
+# DEF-DAG: LOCAL  DEFAULT     1 protected_local
+# DEF-DAG: GLOBAL DEFAULT     1 default_global
+# DEF-DAG: WEAK   DEFAULT     1 default_weak
+# DEF-DAG: GLOBAL DEFAULT     1 internal_global
+# DEF-DAG: WEAK   DEFAULT     1 internal_weak
+# DEF-DAG: GLOBAL DEFAULT     1 hidden_global
+# DEF-DAG: WEAK   DEFAULT     1 hidden_weak
+# DEF-DAG: GLOBAL DEFAULT     1 protected_global
+# DEF-DAG: WEAK   DEFAULT     1 protected_weak
+
+# RUN: cp %t.o %t0.o
+# RUN: llvm-objcopy %t0.o --set-visibility-syms=%t.symbols.regex=hidden --regex
+# RUN: llvm-readelf -s %t0.o | FileCheck %s --check-prefix=HID
+# HID-DAG: LOCAL  HIDDEN      1 default_local
+# HID-DAG: LOCAL  HIDDEN      1 internal_local
+# HID-DAG: LOCAL  HIDDEN      1 hidden_local
+# HID-DAG: LOCAL  HIDDEN      1 protected_local
+# HID-DAG: GLOBAL HIDDEN      1 default_global
+# HID-DAG: WEAK   HIDDEN      1 default_weak
+# HID-DAG: GLOBAL HIDDEN      1 internal_global
+# HID-DAG: WEAK   HIDDEN      1 internal_weak
+# HID-DAG: GLOBAL HIDDEN      1 hidden_global
+# HID-DAG: WEAK   HIDDEN      1 hidden_weak
+# HID-DAG: GLOBAL HIDDEN      1 protected_global
+# HID-DAG: WEAK   HIDDEN      1 protected_weak
+
+# RUN: cp %t.o %t0.o
+# RUN: llvm-objcopy %t0.o --set-visibility-syms=%t.symbols.regex=protected --regex
+# RUN: llvm-readelf -s %t0.o | FileCheck %s --check-prefix=PRO
+# PRO-DAG: LOCAL  PROTECTED   1 default_local
+# PRO-DAG: LOCAL  PROTECTED   1 internal_local
+# PRO-DAG: LOCAL  PROTECTED   1 hidden_local
+# PRO-DAG: LOCAL  PROTECTED   1 protected_local
+# PRO-DAG: GLOBAL PROTECTED   1 default_global
+# PRO-DAG: WEAK   PROTECTED   1 default_weak
+# PRO-DAG: GLOBAL PROTECTED   1 internal_global
+# PRO-DAG: WEAK   PROTECTED   1 internal_weak
+# PRO-DAG: GLOBAL PROTECTED   1 hidden_global
+# PRO-DAG: WEAK   PROTECTED   1 hidden_weak
+# PRO-DAG: GLOBAL PROTECTED   1 protected_global
+# PRO-DAG: WEAK   PROTECTED   1 protected_weak
+
+# RUN: cp %t.o %t0.o
+# RUN: llvm-objcopy %t0.o --set-visibility-syms=%t.symbols.regex=internal --regex
+# RUN: llvm-readelf -s %t0.o | FileCheck %s --check-prefix=INT
+# INT-DAG: LOCAL  INTERNAL    1 default_local
+# INT-DAG: LOCAL  INTERNAL    1 internal_local
+# INT-DAG: LOCAL  INTERNAL    1 hidden_local
+# INT-DAG: LOCAL  INTERNAL    1 protected_local
+# INT-DAG: GLOBAL INTERNAL    1 default_global
+# INT-DAG: WEAK   INTERNAL    1 default_weak
+# INT-DAG: GLOBAL INTERNAL    1 internal_global
+# INT-DAG: WEAK   INTERNAL    1 internal_weak
+# INT-DAG: GLOBAL INTERNAL    1 hidden_global
+# INT-DAG: WEAK   INTERNAL    1 hidden_weak
+# INT-DAG: GLOBAL INTERNAL    1 protected_global
+# INT-DAG: WEAK   INTERNAL    1 protected_weak
+
+# RUN: cp %t.o %t0.o
+# RUN: llvm-objcopy %t0.o --set-visibility-sym=hidden_global=default
+# RUN: llvm-objcopy %t0.o --set-visibility-sym=default_global=hidden
+# RUN: llvm-objcopy %t0.o --set-visibility-sym=default_local=protected
+# RUN: llvm-objcopy %t0.o --set-visibility-sym=protected_global=internal
+# RUN: llvm-readelf -s %t0.o | FileCheck %s --check-prefix=SYM
+# SYM-DAG: LOCAL  PROTECTED   1 default_local
+# SYM-DAG: GLOBAL HIDDEN      1 default_global
+# SYM-DAG: GLOBAL DEFAULT     1 hidden_global
+# SYM-DAG: GLOBAL INTERNAL    1 protected_global
+
+!ELF
+FileHeader:
+  Class:           ELFCLASS64
+  Data:            ELFDATA2LSB
+  Type:            ET_REL
+  Machine:         EM_X86_64
+Sections:
+  - Name:            .text
+    Type:            SHT_PROGBITS
+    Flags:           [ SHF_ALLOC, SHF_EXECINSTR ]
+Symbols:
+  - Name:    default_local
+    Section: .text
+    Binding:  STB_LOCAL
+  - Name:    default_global
+    Section: .text
+    Binding:  STB_GLOBAL
+  - Name:    default_weak
+    Section: .text
+    Binding:  STB_WEAK
+  - Name:    internal_local
+    Section: .text
+    Binding:  STB_LOCAL
+    Other:    [ STV_INTERNAL ]
+  - Name:    internal_global
+    Section: .text
+    Binding:  STB_GLOBAL
+    Other:    [ STV_INTERNAL ]
+  - Name:    internal_weak
+    Section: .text
+    Binding:  STB_WEAK
+    Other:    [ STV_INTERNAL ]
+  - Name:    hidden_local
+    Section: .text
+    Binding:  STB_LOCAL
+    Other:    [ STV_HIDDEN ]
+  - Name:    hidden_global
+    Section: .text
+    Binding:  STB_GLOBAL
+    Other:    [ STV_HIDDEN ]
+  - Name:    hidden_weak
+    Section: .text
+    Binding:  STB_WEAK
+    Other:    [ STV_HIDDEN ]
+  - Name:    protected_local
+    Section: .text
+    Binding:  STB_LOCAL
+    Other:    [ STV_PROTECTED ]
+  - Name:    protected_global
+    Section: .text
+    Binding:  STB_GLOBAL
+    Other:    [ STV_PROTECTED ]
+  - Name:    protected_weak
+    Section: .text
+    Binding:  STB_WEAK
+    Other:    [ STV_PROTECTED ]
+  - Name:    ignored_name
+    Section: .text
+    Binding:  STB_GLOBAL
+    Other:    [ STV_INTERNAL ]
diff --git a/llvm/tools/llvm-objcopy/ObjcopyOptions.cpp b/llvm/tools/llvm-objcopy/ObjcopyOptions.cpp
index f15307181fad61..9fb7d3997039e6 100644
--- a/llvm/tools/llvm-objcopy/ObjcopyOptions.cpp
+++ b/llvm/tools/llvm-objcopy/ObjcopyOptions.cpp
@@ -254,6 +254,21 @@ parseSetSectionFlagValue(StringRef FlagValue) {
   return SFU;
 }
 
+static Expected<uint8_t> parseVisibilityType(StringRef VisType) {
+  const uint8_t Invalid = 0xff;
+  uint8_t type = StringSwitch<uint8_t>(VisType)
+                     .Case("default", ELF::STV_DEFAULT)
+                     .Case("hidden", ELF::STV_HIDDEN)
+                     .Case("internal", ELF::STV_INTERNAL)
+                     .Case("protected", ELF::STV_PROTECTED)
+                     .Default(Invalid);
+  if (type == Invalid)
+    return createStringError(errc::invalid_argument,
+                             "'%s' is not a valid symbol visibility",
+                             VisType.str().c_str());
+  return type;
+}
+
 namespace {
 struct TargetInfo {
   FileFormat Format;
@@ -962,6 +977,34 @@ objcopy::parseObjcopyOptions(ArrayRef<const char *> RawArgsArr,
 
     Config.SymbolsToAdd.push_back(*SymInfo);
   }
+  for (auto *Arg : InputArgs.filtered(OBJCOPY_set_visibility_sym)) {
+    if (!StringRef(Arg->getValue()).contains('='))
+      return createStringError(errc::invalid_argument,
+                               "bad format for --set-visibility-sym");
+    auto SymAndVis = StringRef(Arg->getValue()).split('=');
+    Expected<uint8_t> Type = parseVisibilityType(SymAndVis.second);
+    if (!Type)
+      return Type.takeError();
+    ELFConfig.SetVisibilityType = Type.get();
+    if (Error E =
+            ELFConfig.SymbolsToSetVisibility.addMatcher(NameOrPattern::create(
+                SymAndVis.first, SymbolMatchStyle, ErrorCallback)))
+      return std::move(E);
+  }
+  for (auto *Arg : InputArgs.filtered(OBJCOPY_set_visibility_syms)) {
+    if (!StringRef(Arg->getValue()).contains('='))
+      return createStringError(errc::invalid_argument,
+                               "bad format for --set-visibility-syms");
+    auto FileAndVis = StringRef(Arg->getValue()).split('=');
+    Expected<uint8_t> Type = parseVisibilityType(FileAndVis.second);
+    if (!Type)
+      return Type.takeError();
+    ELFConfig.SetVisibilityType = Type.get();
+    if (Error E = addSymbolsFromFile(ELFConfig.SymbolsToSetVisibility, DC.Alloc,
+                                     FileAndVis.first, SymbolMatchStyle,
+                                     ErrorCallback))
+      return std::move(E);
+  }
 
   ELFConfig.AllowBrokenLinks = InputArgs.hasArg(OBJCOPY_allow_broken_links);
 
diff --git a/llvm/tools/llvm-objcopy/ObjcopyOpts.td b/llvm/tools/llvm-objcopy/ObjcopyOpts.td
index ead8cd28d38779..d872316df5190f 100644
--- a/llvm/tools/llvm-objcopy/ObjcopyOpts.td
+++ b/llvm/tools/llvm-objcopy/ObjcopyOpts.td
@@ -93,6 +93,17 @@ defm set_section_type
          "Set the type of section <section> to the integer <type>">,
       MetaVarName<"section=type">;
 
+defm set_visibility_sym
+    : Eq<"set-visibility-sym",
+         "Change the visibility of a symbol to the specified type">,
+      MetaVarName<"symbol=visibility_type">;
+defm set_visibility_syms
+    : Eq<"set-visibility-syms",
+         "Reads a list of symbols from <filename> and changes their "
+         "visibility to the specified type. Visibility types: default, "
+         "internal, hidden, protected">,
+      MetaVarName<"filename=visibility_type">;
+
 def S : Flag<["-"], "S">,
         Alias<strip_all>,
         HelpText<"Alias for --strip-all">;

>From cc05728dd3d0b05cffdcc2e1e194b9898d30666f Mon Sep 17 00:00:00 2001
From: Ilia Kuklin <ikuklin at accesssoftek.com>
Date: Wed, 7 Feb 2024 00:19:24 +0500
Subject: [PATCH 02/24] Change --set-visibility-sym test check order and
 variable

---
 llvm/test/tools/llvm-objcopy/ELF/set-visibility.test | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/llvm/test/tools/llvm-objcopy/ELF/set-visibility.test b/llvm/test/tools/llvm-objcopy/ELF/set-visibility.test
index bc1c92021c4fe3..008981b0e06c77 100644
--- a/llvm/test/tools/llvm-objcopy/ELF/set-visibility.test
+++ b/llvm/test/tools/llvm-objcopy/ELF/set-visibility.test
@@ -69,12 +69,12 @@
 # RUN: cp %t.o %t0.o
 # RUN: llvm-objcopy %t0.o --set-visibility-sym=hidden_global=default
 # RUN: llvm-objcopy %t0.o --set-visibility-sym=default_global=hidden
-# RUN: llvm-objcopy %t0.o --set-visibility-sym=default_local=protected
+# RUN: llvm-objcopy %t0.o --set-visibility-sym=internal_global=protected
 # RUN: llvm-objcopy %t0.o --set-visibility-sym=protected_global=internal
 # RUN: llvm-readelf -s %t0.o | FileCheck %s --check-prefix=SYM
-# SYM-DAG: LOCAL  PROTECTED   1 default_local
-# SYM-DAG: GLOBAL HIDDEN      1 default_global
 # SYM-DAG: GLOBAL DEFAULT     1 hidden_global
+# SYM-DAG: GLOBAL HIDDEN      1 default_global
+# SYM-DAG: GLOBAL PROTECTED   1 internal_global
 # SYM-DAG: GLOBAL INTERNAL    1 protected_global
 
 !ELF

>From 97b1e2d5236d6c23da52199e4f78035d7c2515c5 Mon Sep 17 00:00:00 2001
From: Ilia Kuklin <ikuklin at accesssoftek.com>
Date: Thu, 8 Feb 2024 22:23:18 +0500
Subject: [PATCH 03/24] Move setting the visibility to after localizing hidden
 symbols

---
 llvm/lib/ObjCopy/ELF/ELFObjcopy.cpp | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/llvm/lib/ObjCopy/ELF/ELFObjcopy.cpp b/llvm/lib/ObjCopy/ELF/ELFObjcopy.cpp
index b768b7c5d05d7b..500306c5b70476 100644
--- a/llvm/lib/ObjCopy/ELF/ELFObjcopy.cpp
+++ b/llvm/lib/ObjCopy/ELF/ELFObjcopy.cpp
@@ -290,9 +290,6 @@ static Error updateAndRemoveSymbols(const CommonConfig &Config,
     return Error::success();
 
   Obj.SymbolTable->updateSymbols([&](Symbol &Sym) {
-    if (ELFConfig.SymbolsToSetVisibility.matches(Sym.Name) &&
-        Sym.getShndx() != SHN_UNDEF)
-      Sym.Visibility = ELFConfig.SetVisibilityType;
     // 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 &&
@@ -301,6 +298,10 @@ static Error updateAndRemoveSymbols(const CommonConfig &Config,
          Config.SymbolsToLocalize.matches(Sym.Name)))
       Sym.Binding = STB_LOCAL;
 
+    if (ELFConfig.SymbolsToSetVisibility.matches(Sym.Name) &&
+        Sym.getShndx() != SHN_UNDEF)
+      Sym.Visibility = ELFConfig.SetVisibilityType;
+
     // Note: these two globalize flags have very similar names but different
     // meanings:
     //

>From d3104d156d5afbfdfbf08cba3389e450b6eed250 Mon Sep 17 00:00:00 2001
From: Ilia Kuklin <ikuklin at accesssoftek.com>
Date: Thu, 8 Feb 2024 22:25:56 +0500
Subject: [PATCH 04/24] Change code formatting in when parsing the options

---
 llvm/tools/llvm-objcopy/ObjcopyOptions.cpp | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/llvm/tools/llvm-objcopy/ObjcopyOptions.cpp b/llvm/tools/llvm-objcopy/ObjcopyOptions.cpp
index 9fb7d3997039e6..9d995c79d22b30 100644
--- a/llvm/tools/llvm-objcopy/ObjcopyOptions.cpp
+++ b/llvm/tools/llvm-objcopy/ObjcopyOptions.cpp
@@ -981,27 +981,27 @@ objcopy::parseObjcopyOptions(ArrayRef<const char *> RawArgsArr,
     if (!StringRef(Arg->getValue()).contains('='))
       return createStringError(errc::invalid_argument,
                                "bad format for --set-visibility-sym");
-    auto SymAndVis = StringRef(Arg->getValue()).split('=');
-    Expected<uint8_t> Type = parseVisibilityType(SymAndVis.second);
+    auto [Sym, Visibility] = StringRef(Arg->getValue()).split('=');
+    Expected<uint8_t> Type = parseVisibilityType(Visibility);
     if (!Type)
       return Type.takeError();
-    ELFConfig.SetVisibilityType = Type.get();
+    ELFConfig.SetVisibilityType = *Type;
     if (Error E =
             ELFConfig.SymbolsToSetVisibility.addMatcher(NameOrPattern::create(
-                SymAndVis.first, SymbolMatchStyle, ErrorCallback)))
+                Sym, SymbolMatchStyle, ErrorCallback)))
       return std::move(E);
   }
   for (auto *Arg : InputArgs.filtered(OBJCOPY_set_visibility_syms)) {
     if (!StringRef(Arg->getValue()).contains('='))
       return createStringError(errc::invalid_argument,
                                "bad format for --set-visibility-syms");
-    auto FileAndVis = StringRef(Arg->getValue()).split('=');
-    Expected<uint8_t> Type = parseVisibilityType(FileAndVis.second);
+    auto [File, Visibility] = StringRef(Arg->getValue()).split('=');
+    Expected<uint8_t> Type = parseVisibilityType(Visibility);
     if (!Type)
       return Type.takeError();
-    ELFConfig.SetVisibilityType = Type.get();
+    ELFConfig.SetVisibilityType = *Type;
     if (Error E = addSymbolsFromFile(ELFConfig.SymbolsToSetVisibility, DC.Alloc,
-                                     FileAndVis.first, SymbolMatchStyle,
+                                     File, SymbolMatchStyle,
                                      ErrorCallback))
       return std::move(E);
   }

>From 524b13f284a91c565bfcb1d262134148d37b2836 Mon Sep 17 00:00:00 2001
From: Ilia Kuklin <ikuklin at accesssoftek.com>
Date: Thu, 8 Feb 2024 22:26:54 +0500
Subject: [PATCH 05/24] Add checks for multiple uses of setting visibility

---
 llvm/tools/llvm-objcopy/ObjcopyOptions.cpp | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/llvm/tools/llvm-objcopy/ObjcopyOptions.cpp b/llvm/tools/llvm-objcopy/ObjcopyOptions.cpp
index 9d995c79d22b30..a6f8c8cf7b48ef 100644
--- a/llvm/tools/llvm-objcopy/ObjcopyOptions.cpp
+++ b/llvm/tools/llvm-objcopy/ObjcopyOptions.cpp
@@ -978,6 +978,9 @@ objcopy::parseObjcopyOptions(ArrayRef<const char *> RawArgsArr,
     Config.SymbolsToAdd.push_back(*SymInfo);
   }
   for (auto *Arg : InputArgs.filtered(OBJCOPY_set_visibility_sym)) {
+    if (!ELFConfig.SymbolsToSetVisibility.empty())
+      return createStringError(errc::invalid_argument,
+                               "multiple specifications of visibility type");
     if (!StringRef(Arg->getValue()).contains('='))
       return createStringError(errc::invalid_argument,
                                "bad format for --set-visibility-sym");
@@ -992,6 +995,9 @@ objcopy::parseObjcopyOptions(ArrayRef<const char *> RawArgsArr,
       return std::move(E);
   }
   for (auto *Arg : InputArgs.filtered(OBJCOPY_set_visibility_syms)) {
+    if (!ELFConfig.SymbolsToSetVisibility.empty())
+      return createStringError(errc::invalid_argument,
+                               "multiple specifications of visibility type");
     if (!StringRef(Arg->getValue()).contains('='))
       return createStringError(errc::invalid_argument,
                                "bad format for --set-visibility-syms");

>From 9ec88f20a28d9612b5f80cf1fa2e522e67f981c3 Mon Sep 17 00:00:00 2001
From: Ilia Kuklin <ikuklin at accesssoftek.com>
Date: Thu, 8 Feb 2024 22:28:07 +0500
Subject: [PATCH 06/24] Adjust and separate tests of setting visibility
 functionality

---
 .../llvm-objcopy/ELF/set-visibility-sym.test  | 106 ++++++++++++
 .../llvm-objcopy/ELF/set-visibility-syms.test | 155 ++++++++++++++++++
 2 files changed, 261 insertions(+)
 create mode 100644 llvm/test/tools/llvm-objcopy/ELF/set-visibility-sym.test
 create mode 100644 llvm/test/tools/llvm-objcopy/ELF/set-visibility-syms.test

diff --git a/llvm/test/tools/llvm-objcopy/ELF/set-visibility-sym.test b/llvm/test/tools/llvm-objcopy/ELF/set-visibility-sym.test
new file mode 100644
index 00000000000000..0cae042914589c
--- /dev/null
+++ b/llvm/test/tools/llvm-objcopy/ELF/set-visibility-sym.test
@@ -0,0 +1,106 @@
+
+# RUN: yaml2obj %s -o %t.o
+
+# Check if the visibility of a single symbol is set correctly,
+# and none of other symbols are affected
+# RUN: cp %t.o %t0.o
+# RUN: llvm-objcopy %t0.o --set-visibility-sym=default_local=hidden
+# RUN: llvm-objcopy %t0.o --set-visibility-sym=internal_local=protected
+# RUN: llvm-objcopy %t0.o --set-visibility-sym=hidden_local=internal
+# RUN: llvm-objcopy %t0.o --set-visibility-sym=protected_local=default
+# RUN: llvm-readelf -s %t0.o | FileCheck %s --check-prefix=SINGLE
+
+# SINGLE-DAG: HIDDEN      1 default_local
+# SINGLE-DAG: PROTECTED   1 internal_local
+# SINGLE-DAG: INTERNAL    1 hidden_local
+# SINGLE-DAG: DEFAULT     1 protected_local
+# Unaffected symbols:
+# SINGLE-DAG: DEFAULT     1 default_global
+# SINGLE-DAG: DEFAULT     1 default_weak
+# SINGLE-DAG: INTERNAL    1 internal_global
+# SINGLE-DAG: INTERNAL    1 internal_weak
+# SINGLE-DAG: HIDDEN      1 hidden_global
+# SINGLE-DAG: HIDDEN      1 hidden_weak
+# SINGLE-DAG: PROTECTED   1 protected_global
+# SINGLE-DAG: PROTECTED   1 protected_weak
+
+
+# Check if the visibility of symbols specified by a regex are set correctly,
+# and none of other symbols are affected
+# RUN: llvm-objcopy %t.o %t1.o --set-visibility-sym=.*_local=hidden --regex
+# RUN: llvm-readelf -s %t1.o | FileCheck %s --check-prefix=REGEX
+
+# REGEX-DAG: HIDDEN      1 default_local
+# REGEX-DAG: HIDDEN      1 internal_local
+# REGEX-DAG: HIDDEN      1 hidden_local
+# REGEX-DAG: HIDDEN      1 protected_local
+# Unaffected symbols:
+# REGEX-DAG: DEFAULT     1 default_global
+# REGEX-DAG: DEFAULT     1 default_weak
+# REGEX-DAG: INTERNAL    1 internal_global
+# REGEX-DAG: INTERNAL    1 internal_weak
+# REGEX-DAG: HIDDEN      1 hidden_global
+# REGEX-DAG: HIDDEN      1 hidden_weak
+# REGEX-DAG: PROTECTED   1 protected_global
+# REGEX-DAG: PROTECTED   1 protected_weak
+
+
+!ELF
+FileHeader:
+  Class:           ELFCLASS64
+  Data:            ELFDATA2LSB
+  Type:            ET_REL
+  Machine:         EM_X86_64
+Sections:
+  - Name:            .text
+    Type:            SHT_PROGBITS
+Symbols:
+  - Name:    default_local
+    Section: .text
+    Binding:  STB_LOCAL
+  - Name:    default_global
+    Section: .text
+    Binding:  STB_GLOBAL
+  - Name:    default_weak
+    Section: .text
+    Binding:  STB_WEAK
+  - Name:    internal_local
+    Section: .text
+    Binding:  STB_LOCAL
+    Other:    [ STV_INTERNAL ]
+  - Name:    internal_global
+    Section: .text
+    Binding:  STB_GLOBAL
+    Other:    [ STV_INTERNAL ]
+  - Name:    internal_weak
+    Section: .text
+    Binding:  STB_WEAK
+    Other:    [ STV_INTERNAL ]
+  - Name:    hidden_local
+    Section: .text
+    Binding:  STB_LOCAL
+    Other:    [ STV_HIDDEN ]
+  - Name:    hidden_global
+    Section: .text
+    Binding:  STB_GLOBAL
+    Other:    [ STV_HIDDEN ]
+  - Name:    hidden_weak
+    Section: .text
+    Binding:  STB_WEAK
+    Other:    [ STV_HIDDEN ]
+  - Name:    protected_local
+    Section: .text
+    Binding:  STB_LOCAL
+    Other:    [ STV_PROTECTED ]
+  - Name:    protected_global
+    Section: .text
+    Binding:  STB_GLOBAL
+    Other:    [ STV_PROTECTED ]
+  - Name:    protected_weak
+    Section: .text
+    Binding:  STB_WEAK
+    Other:    [ STV_PROTECTED ]
+  - Name:    ignored_name
+    Section: .text
+    Binding:  STB_GLOBAL
+    Other:    [ STV_INTERNAL ]
diff --git a/llvm/test/tools/llvm-objcopy/ELF/set-visibility-syms.test b/llvm/test/tools/llvm-objcopy/ELF/set-visibility-syms.test
new file mode 100644
index 00000000000000..d3fe8ca8229e38
--- /dev/null
+++ b/llvm/test/tools/llvm-objcopy/ELF/set-visibility-syms.test
@@ -0,0 +1,155 @@
+
+# RUN: yaml2obj %s -o %t.o
+# RUN: echo '.*' > %t.symbols.regex
+
+# Check if the visibility of all symbols is properly set to DEFAULT
+# RUN: llvm-objcopy %t.o %t0.o --set-visibility-syms=%t.symbols.regex=default --regex
+# RUN: llvm-readelf -s %t0.o | FileCheck %s --check-prefix=DEF
+
+# DEF-DAG: DEFAULT     1 default_local
+# DEF-DAG: DEFAULT     1 internal_local
+# DEF-DAG: DEFAULT     1 hidden_local
+# DEF-DAG: DEFAULT     1 protected_local
+# DEF-DAG: DEFAULT     1 default_global
+# DEF-DAG: DEFAULT     1 default_weak
+# DEF-DAG: DEFAULT     1 internal_global
+# DEF-DAG: DEFAULT     1 internal_weak
+# DEF-DAG: DEFAULT     1 hidden_global
+# DEF-DAG: DEFAULT     1 hidden_weak
+# DEF-DAG: DEFAULT     1 protected_global
+# DEF-DAG: DEFAULT     1 protected_weak
+
+
+# Check if the visibility of all symbols is properly set to HIDDEN
+# RUN: llvm-objcopy %t.o %t1.o --set-visibility-syms=%t.symbols.regex=hidden --regex
+# RUN: llvm-readelf -s %t1.o | FileCheck %s --check-prefix=HID
+
+# HID-DAG: HIDDEN      1 default_local
+# HID-DAG: HIDDEN      1 internal_local
+# HID-DAG: HIDDEN      1 hidden_local
+# HID-DAG: HIDDEN      1 protected_local
+# HID-DAG: HIDDEN      1 default_global
+# HID-DAG: HIDDEN      1 default_weak
+# HID-DAG: HIDDEN      1 internal_global
+# HID-DAG: HIDDEN      1 internal_weak
+# HID-DAG: HIDDEN      1 hidden_global
+# HID-DAG: HIDDEN      1 hidden_weak
+# HID-DAG: HIDDEN      1 protected_global
+# HID-DAG: HIDDEN      1 protected_weak
+
+
+# Check if the visibility of all symbols is properly set to PROTECTED
+# RUN: llvm-objcopy %t.o %t2.o --set-visibility-syms=%t.symbols.regex=protected --regex
+# RUN: llvm-readelf -s %t2.o | FileCheck %s --check-prefix=PRO
+
+# PRO-DAG: PROTECTED   1 default_local
+# PRO-DAG: PROTECTED   1 internal_local
+# PRO-DAG: PROTECTED   1 hidden_local
+# PRO-DAG: PROTECTED   1 protected_local
+# PRO-DAG: PROTECTED   1 default_global
+# PRO-DAG: PROTECTED   1 default_weak
+# PRO-DAG: PROTECTED   1 internal_global
+# PRO-DAG: PROTECTED   1 internal_weak
+# PRO-DAG: PROTECTED   1 hidden_global
+# PRO-DAG: PROTECTED   1 hidden_weak
+# PRO-DAG: PROTECTED   1 protected_global
+# PRO-DAG: PROTECTED   1 protected_weak
+
+
+# Check if the visibility of all symbols is properly set to INTERNAL
+# RUN: llvm-objcopy %t.o %t3.o --set-visibility-syms=%t.symbols.regex=internal --regex
+# RUN: llvm-readelf -s %t3.o | FileCheck %s --check-prefix=INT
+
+# INT-DAG: INTERNAL    1 default_local
+# INT-DAG: INTERNAL    1 internal_local
+# INT-DAG: INTERNAL    1 hidden_local
+# INT-DAG: INTERNAL    1 protected_local
+# INT-DAG: INTERNAL    1 default_global
+# INT-DAG: INTERNAL    1 default_weak
+# INT-DAG: INTERNAL    1 internal_global
+# INT-DAG: INTERNAL    1 internal_weak
+# INT-DAG: INTERNAL    1 hidden_global
+# INT-DAG: INTERNAL    1 hidden_weak
+# INT-DAG: INTERNAL    1 protected_global
+# INT-DAG: INTERNAL    1 protected_weak
+
+
+# Check if setting the visibility of certain symbols that were read from
+# a file does not affect other symbols
+# RUN: echo -e "default_local\ninternal_local" > %t.symbol.list
+# RUN: llvm-objcopy %t.o %t3.o --set-visibility-syms=%t.symbol.list=hidden
+# RUN: llvm-readelf -s %t3.o | FileCheck %s --check-prefix=FILE
+
+# FILE-DAG: HIDDEN      1 default_local
+# FILE-DAG: HIDDEN      1 internal_local
+# Unaffected symbols:
+# FILE-DAG: HIDDEN      1 hidden_local
+# FILE-DAG: PROTECTED   1 protected_local
+# FILE-DAG: DEFAULT     1 default_global
+# FILE-DAG: DEFAULT     1 default_weak
+# FILE-DAG: INTERNAL    1 internal_global
+# FILE-DAG: INTERNAL    1 internal_weak
+# FILE-DAG: HIDDEN      1 hidden_global
+# FILE-DAG: HIDDEN      1 hidden_weak
+# FILE-DAG: PROTECTED   1 protected_global
+# FILE-DAG: PROTECTED   1 protected_weak
+
+!ELF
+FileHeader:
+  Class:           ELFCLASS64
+  Data:            ELFDATA2LSB
+  Type:            ET_REL
+  Machine:         EM_X86_64
+Sections:
+  - Name:            .text
+    Type:            SHT_PROGBITS
+Symbols:
+  - Name:    default_local
+    Section: .text
+    Binding:  STB_LOCAL
+  - Name:    default_global
+    Section: .text
+    Binding:  STB_GLOBAL
+  - Name:    default_weak
+    Section: .text
+    Binding:  STB_WEAK
+  - Name:    internal_local
+    Section: .text
+    Binding:  STB_LOCAL
+    Other:    [ STV_INTERNAL ]
+  - Name:    internal_global
+    Section: .text
+    Binding:  STB_GLOBAL
+    Other:    [ STV_INTERNAL ]
+  - Name:    internal_weak
+    Section: .text
+    Binding:  STB_WEAK
+    Other:    [ STV_INTERNAL ]
+  - Name:    hidden_local
+    Section: .text
+    Binding:  STB_LOCAL
+    Other:    [ STV_HIDDEN ]
+  - Name:    hidden_global
+    Section: .text
+    Binding:  STB_GLOBAL
+    Other:    [ STV_HIDDEN ]
+  - Name:    hidden_weak
+    Section: .text
+    Binding:  STB_WEAK
+    Other:    [ STV_HIDDEN ]
+  - Name:    protected_local
+    Section: .text
+    Binding:  STB_LOCAL
+    Other:    [ STV_PROTECTED ]
+  - Name:    protected_global
+    Section: .text
+    Binding:  STB_GLOBAL
+    Other:    [ STV_PROTECTED ]
+  - Name:    protected_weak
+    Section: .text
+    Binding:  STB_WEAK
+    Other:    [ STV_PROTECTED ]
+  - Name:    ignored_name
+    Section: .text
+    Binding:  STB_GLOBAL
+    Other:    [ STV_INTERNAL ]

>From 450e1f622c446651059cdb62127ed6356b23b6ef Mon Sep 17 00:00:00 2001
From: Ilia Kuklin <ikuklin at accesssoftek.com>
Date: Thu, 8 Feb 2024 22:28:59 +0500
Subject: [PATCH 07/24] Add a test for checking various error cases

---
 .../ELF/set-visibility-check-errors.test      | 43 +++++++++++++++++++
 1 file changed, 43 insertions(+)
 create mode 100644 llvm/test/tools/llvm-objcopy/ELF/set-visibility-check-errors.test

diff --git a/llvm/test/tools/llvm-objcopy/ELF/set-visibility-check-errors.test b/llvm/test/tools/llvm-objcopy/ELF/set-visibility-check-errors.test
new file mode 100644
index 00000000000000..2555d727f031fe
--- /dev/null
+++ b/llvm/test/tools/llvm-objcopy/ELF/set-visibility-check-errors.test
@@ -0,0 +1,43 @@
+
+# RUN: yaml2obj %s -o %t.o
+# RUN: echo 'foo' > %t.symbols
+
+# Check if passing an invalid visibility type generates an error message
+# RUN: not llvm-objcopy %t.o --set-visibility-syms=%t.symbols=invalid-type --regex 2>&1 | FileCheck %s --check-prefix=TYPE
+# RUN: not llvm-objcopy %t.o --set-visibility-sym=foo=invalid-type --regex 2>&1 | FileCheck %s --check-prefix=TYPE
+# TYPE: error: 'invalid-type' is not a valid symbol visibility
+
+# Check if using the option multiple times generates an error message
+# RUN: not llvm-objcopy %t.o --set-visibility-syms=%t.symbols=hidden \
+# RUN:                       --set-visibility-syms=%t.symbols=default \
+# RUN:                       --regex 2>&1 | FileCheck %s --check-prefix=MULTIPLE
+# RUN: not llvm-objcopy %t.o --set-visibility-sym=foo=hidden \
+# RUN:                       --set-visibility-sym=bar=default \
+# RUN:                       --regex 2>&1 | FileCheck %s --check-prefix=MULTIPLE
+# RUN: not llvm-objcopy %t.o --set-visibility-syms=%t.symbols=hidden \
+# RUN:                       --set-visibility-sym=bar=default \
+# RUN:                       --regex 2>&1 | FileCheck %s --check-prefix=MULTIPLE
+# MULTIPLE: error: multiple specifications of visibility type
+
+# Check if not using the proper format with character '=' generates an error
+# RUN: not llvm-objcopy %t.o --set-visibility-syms=%t.symbols,hidden 2>&1 | FileCheck %s --check-prefix=FORMAT
+# RUN: not llvm-objcopy %t.o --set-visibility-sym=foo default 2>&1 | FileCheck %s --check-prefix=FORMAT
+# FORMAT: error: bad format for --set-visibility-sym
+
+# Check if using an invalid symbol pattern generates an error
+# RUN: echo '*.' > %t.symbols.regex
+# RUN: not llvm-objcopy %t.o --set-visibility-syms=%t.symbols.regex=hidden --regex 2>&1 | FileCheck %s --check-prefix=SYMBOL
+# RUN: not llvm-objcopy %t.o --set-visibility-sym=*.=default --regex 2>&1 | FileCheck %s --check-prefix=SYMBOL
+# SYMBOL: error: cannot compile regular expression '*.': repetition-operator operand invalid
+
+# Check passing an invalid filename generates an error
+# RUN: not llvm-objcopy %t.o --set-visibility-syms=no_file=hidden 2>&1 | FileCheck %s --check-prefix=FILE
+# FILE: error: 'no_file': No such file or directory
+
+
+!ELF
+FileHeader:
+  Class:           ELFCLASS64
+  Data:            ELFDATA2LSB
+  Type:            ET_REL
+  Machine:         EM_X86_64

>From 20a8c43baa85fb2b0733362928c1a3cbe7edc614 Mon Sep 17 00:00:00 2001
From: Ilia Kuklin <ikuklin at accesssoftek.com>
Date: Thu, 8 Feb 2024 22:29:59 +0500
Subject: [PATCH 08/24] Add a test for ingoring SHN_UNDEF symbols

---
 .../ELF/set-visibility-undef-symbol.test      | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)
 create mode 100644 llvm/test/tools/llvm-objcopy/ELF/set-visibility-undef-symbol.test

diff --git a/llvm/test/tools/llvm-objcopy/ELF/set-visibility-undef-symbol.test b/llvm/test/tools/llvm-objcopy/ELF/set-visibility-undef-symbol.test
new file mode 100644
index 00000000000000..e7a22a09351b3a
--- /dev/null
+++ b/llvm/test/tools/llvm-objcopy/ELF/set-visibility-undef-symbol.test
@@ -0,0 +1,19 @@
+
+# Check if symbols with SHN_UNDEF index are ignored when setting visibility
+
+# RUN: yaml2obj %s -o %t.o
+# RUN: llvm-objcopy %t.o --set-visibility-sym=foo=hidden
+# RUN: llvm-readelf -s %t.o | FileCheck %s
+
+# CHECK: DEFAULT   UND foo
+
+!ELF
+FileHeader:
+  Class:           ELFCLASS64
+  Data:            ELFDATA2LSB
+  Type:            ET_REL
+  Machine:         EM_X86_64
+Symbols:
+  - Name:     foo
+    Binding:  STB_LOCAL
+    Index:    SHN_UNDEF

>From f6b659b986d51f12e283174c6a2cc90c06549ee7 Mon Sep 17 00:00:00 2001
From: Ilia Kuklin <ikuklin at accesssoftek.com>
Date: Thu, 8 Feb 2024 22:30:55 +0500
Subject: [PATCH 09/24] Update the llvm-objcopy documentation

---
 llvm/docs/CommandGuide/llvm-objcopy.rst | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/llvm/docs/CommandGuide/llvm-objcopy.rst b/llvm/docs/CommandGuide/llvm-objcopy.rst
index 6e13cd94b92fda..f150fdd7ec51ac 100644
--- a/llvm/docs/CommandGuide/llvm-objcopy.rst
+++ b/llvm/docs/CommandGuide/llvm-objcopy.rst
@@ -450,6 +450,15 @@ them.
  Set the start address of the output to ``<addr>``. Overrides any previously
  specified :option:`--change-start` or :option:`--adjust-start` options.
 
+.. option:: --set-visibility-sym <symbol>=<visibility_type>
+
+ Change the visibility of a symbol to the specified type.
+
+.. option:: --set-visibility-syms <filename>=<visibility_type>
+
+ Reads a list of symbols from <filename> and changes their visibility to the
+ specified type. Visibility types: default, internal, hidden, protected.
+
 .. option:: --split-dwo <dwo-file>
 
  Equivalent to running :program:`llvm-objcopy` with :option:`--extract-dwo` and

>From c6faec2bfdd0dbae8f0dcface73d302f38e308e3 Mon Sep 17 00:00:00 2001
From: Ilia Kuklin <ikuklin at accesssoftek.com>
Date: Thu, 8 Feb 2024 22:52:38 +0500
Subject: [PATCH 10/24] Rename --set-visibility-sym to --set-symbol-visibility

---
 llvm/docs/CommandGuide/llvm-objcopy.rst       |   4 +-
 .../ELF/set-visibility-check-errors.test      |  28 ++--
 ...ty-sym.test => set-visibility-symbol.test} |  10 +-
 ...-syms.test => set-visibility-symbols.test} |  10 +-
 .../ELF/set-visibility-undef-symbol.test      |   2 +-
 .../llvm-objcopy/ELF/set-visibility.test      | 139 ------------------
 llvm/tools/llvm-objcopy/ObjcopyOptions.cpp    |   8 +-
 llvm/tools/llvm-objcopy/ObjcopyOpts.td        |   8 +-
 8 files changed, 35 insertions(+), 174 deletions(-)
 rename llvm/test/tools/llvm-objcopy/ELF/{set-visibility-sym.test => set-visibility-symbol.test} (88%)
 rename llvm/test/tools/llvm-objcopy/ELF/{set-visibility-syms.test => set-visibility-symbols.test} (91%)
 delete mode 100644 llvm/test/tools/llvm-objcopy/ELF/set-visibility.test

diff --git a/llvm/docs/CommandGuide/llvm-objcopy.rst b/llvm/docs/CommandGuide/llvm-objcopy.rst
index f150fdd7ec51ac..4b964e9ce82fb2 100644
--- a/llvm/docs/CommandGuide/llvm-objcopy.rst
+++ b/llvm/docs/CommandGuide/llvm-objcopy.rst
@@ -450,11 +450,11 @@ them.
  Set the start address of the output to ``<addr>``. Overrides any previously
  specified :option:`--change-start` or :option:`--adjust-start` options.
 
-.. option:: --set-visibility-sym <symbol>=<visibility_type>
+.. option:: --set-symbol-visibility <symbol>=<visibility_type>
 
  Change the visibility of a symbol to the specified type.
 
-.. option:: --set-visibility-syms <filename>=<visibility_type>
+.. option:: --set-symbols-visibility <filename>=<visibility_type>
 
  Reads a list of symbols from <filename> and changes their visibility to the
  specified type. Visibility types: default, internal, hidden, protected.
diff --git a/llvm/test/tools/llvm-objcopy/ELF/set-visibility-check-errors.test b/llvm/test/tools/llvm-objcopy/ELF/set-visibility-check-errors.test
index 2555d727f031fe..dd67a9863a089c 100644
--- a/llvm/test/tools/llvm-objcopy/ELF/set-visibility-check-errors.test
+++ b/llvm/test/tools/llvm-objcopy/ELF/set-visibility-check-errors.test
@@ -3,35 +3,35 @@
 # RUN: echo 'foo' > %t.symbols
 
 # Check if passing an invalid visibility type generates an error message
-# RUN: not llvm-objcopy %t.o --set-visibility-syms=%t.symbols=invalid-type --regex 2>&1 | FileCheck %s --check-prefix=TYPE
-# RUN: not llvm-objcopy %t.o --set-visibility-sym=foo=invalid-type --regex 2>&1 | FileCheck %s --check-prefix=TYPE
+# RUN: not llvm-objcopy %t.o --set-symbols-visibility=%t.symbols=invalid-type --regex 2>&1 | FileCheck %s --check-prefix=TYPE
+# RUN: not llvm-objcopy %t.o --set-symbol-visibility=foo=invalid-type --regex 2>&1 | FileCheck %s --check-prefix=TYPE
 # TYPE: error: 'invalid-type' is not a valid symbol visibility
 
 # Check if using the option multiple times generates an error message
-# RUN: not llvm-objcopy %t.o --set-visibility-syms=%t.symbols=hidden \
-# RUN:                       --set-visibility-syms=%t.symbols=default \
+# RUN: not llvm-objcopy %t.o --set-symbols-visibility=%t.symbols=hidden \
+# RUN:                       --set-symbols-visibility=%t.symbols=default \
 # RUN:                       --regex 2>&1 | FileCheck %s --check-prefix=MULTIPLE
-# RUN: not llvm-objcopy %t.o --set-visibility-sym=foo=hidden \
-# RUN:                       --set-visibility-sym=bar=default \
+# RUN: not llvm-objcopy %t.o --set-symbol-visibility=foo=hidden \
+# RUN:                       --set-symbol-visibility=bar=default \
 # RUN:                       --regex 2>&1 | FileCheck %s --check-prefix=MULTIPLE
-# RUN: not llvm-objcopy %t.o --set-visibility-syms=%t.symbols=hidden \
-# RUN:                       --set-visibility-sym=bar=default \
+# RUN: not llvm-objcopy %t.o --set-symbols-visibility=%t.symbols=hidden \
+# RUN:                       --set-symbol-visibility=bar=default \
 # RUN:                       --regex 2>&1 | FileCheck %s --check-prefix=MULTIPLE
 # MULTIPLE: error: multiple specifications of visibility type
 
 # Check if not using the proper format with character '=' generates an error
-# RUN: not llvm-objcopy %t.o --set-visibility-syms=%t.symbols,hidden 2>&1 | FileCheck %s --check-prefix=FORMAT
-# RUN: not llvm-objcopy %t.o --set-visibility-sym=foo default 2>&1 | FileCheck %s --check-prefix=FORMAT
-# FORMAT: error: bad format for --set-visibility-sym
+# RUN: not llvm-objcopy %t.o --set-symbols-visibility=%t.symbols,hidden 2>&1 | FileCheck %s --check-prefix=FORMAT
+# RUN: not llvm-objcopy %t.o --set-symbol-visibility=foo default 2>&1 | FileCheck %s --check-prefix=FORMAT
+# FORMAT: error: bad format for --set-symbol{{.?}}-visibility
 
 # Check if using an invalid symbol pattern generates an error
 # RUN: echo '*.' > %t.symbols.regex
-# RUN: not llvm-objcopy %t.o --set-visibility-syms=%t.symbols.regex=hidden --regex 2>&1 | FileCheck %s --check-prefix=SYMBOL
-# RUN: not llvm-objcopy %t.o --set-visibility-sym=*.=default --regex 2>&1 | FileCheck %s --check-prefix=SYMBOL
+# RUN: not llvm-objcopy %t.o --set-symbols-visibility=%t.symbols.regex=hidden --regex 2>&1 | FileCheck %s --check-prefix=SYMBOL
+# RUN: not llvm-objcopy %t.o --set-symbol-visibility=*.=default --regex 2>&1 | FileCheck %s --check-prefix=SYMBOL
 # SYMBOL: error: cannot compile regular expression '*.': repetition-operator operand invalid
 
 # Check passing an invalid filename generates an error
-# RUN: not llvm-objcopy %t.o --set-visibility-syms=no_file=hidden 2>&1 | FileCheck %s --check-prefix=FILE
+# RUN: not llvm-objcopy %t.o --set-symbols-visibility=no_file=hidden 2>&1 | FileCheck %s --check-prefix=FILE
 # FILE: error: 'no_file': No such file or directory
 
 
diff --git a/llvm/test/tools/llvm-objcopy/ELF/set-visibility-sym.test b/llvm/test/tools/llvm-objcopy/ELF/set-visibility-symbol.test
similarity index 88%
rename from llvm/test/tools/llvm-objcopy/ELF/set-visibility-sym.test
rename to llvm/test/tools/llvm-objcopy/ELF/set-visibility-symbol.test
index 0cae042914589c..6b6588d2ed3fff 100644
--- a/llvm/test/tools/llvm-objcopy/ELF/set-visibility-sym.test
+++ b/llvm/test/tools/llvm-objcopy/ELF/set-visibility-symbol.test
@@ -4,10 +4,10 @@
 # Check if the visibility of a single symbol is set correctly,
 # and none of other symbols are affected
 # RUN: cp %t.o %t0.o
-# RUN: llvm-objcopy %t0.o --set-visibility-sym=default_local=hidden
-# RUN: llvm-objcopy %t0.o --set-visibility-sym=internal_local=protected
-# RUN: llvm-objcopy %t0.o --set-visibility-sym=hidden_local=internal
-# RUN: llvm-objcopy %t0.o --set-visibility-sym=protected_local=default
+# RUN: llvm-objcopy %t0.o --set-symbol-visibility=default_local=hidden
+# RUN: llvm-objcopy %t0.o --set-symbol-visibility=internal_local=protected
+# RUN: llvm-objcopy %t0.o --set-symbol-visibility=hidden_local=internal
+# RUN: llvm-objcopy %t0.o --set-symbol-visibility=protected_local=default
 # RUN: llvm-readelf -s %t0.o | FileCheck %s --check-prefix=SINGLE
 
 # SINGLE-DAG: HIDDEN      1 default_local
@@ -27,7 +27,7 @@
 
 # Check if the visibility of symbols specified by a regex are set correctly,
 # and none of other symbols are affected
-# RUN: llvm-objcopy %t.o %t1.o --set-visibility-sym=.*_local=hidden --regex
+# RUN: llvm-objcopy %t.o %t1.o --set-symbol-visibility=.*_local=hidden --regex
 # RUN: llvm-readelf -s %t1.o | FileCheck %s --check-prefix=REGEX
 
 # REGEX-DAG: HIDDEN      1 default_local
diff --git a/llvm/test/tools/llvm-objcopy/ELF/set-visibility-syms.test b/llvm/test/tools/llvm-objcopy/ELF/set-visibility-symbols.test
similarity index 91%
rename from llvm/test/tools/llvm-objcopy/ELF/set-visibility-syms.test
rename to llvm/test/tools/llvm-objcopy/ELF/set-visibility-symbols.test
index d3fe8ca8229e38..99c417f76304da 100644
--- a/llvm/test/tools/llvm-objcopy/ELF/set-visibility-syms.test
+++ b/llvm/test/tools/llvm-objcopy/ELF/set-visibility-symbols.test
@@ -3,7 +3,7 @@
 # RUN: echo '.*' > %t.symbols.regex
 
 # Check if the visibility of all symbols is properly set to DEFAULT
-# RUN: llvm-objcopy %t.o %t0.o --set-visibility-syms=%t.symbols.regex=default --regex
+# RUN: llvm-objcopy %t.o %t0.o --set-symbols-visibility=%t.symbols.regex=default --regex
 # RUN: llvm-readelf -s %t0.o | FileCheck %s --check-prefix=DEF
 
 # DEF-DAG: DEFAULT     1 default_local
@@ -21,7 +21,7 @@
 
 
 # Check if the visibility of all symbols is properly set to HIDDEN
-# RUN: llvm-objcopy %t.o %t1.o --set-visibility-syms=%t.symbols.regex=hidden --regex
+# RUN: llvm-objcopy %t.o %t1.o --set-symbols-visibility=%t.symbols.regex=hidden --regex
 # RUN: llvm-readelf -s %t1.o | FileCheck %s --check-prefix=HID
 
 # HID-DAG: HIDDEN      1 default_local
@@ -39,7 +39,7 @@
 
 
 # Check if the visibility of all symbols is properly set to PROTECTED
-# RUN: llvm-objcopy %t.o %t2.o --set-visibility-syms=%t.symbols.regex=protected --regex
+# RUN: llvm-objcopy %t.o %t2.o --set-symbols-visibility=%t.symbols.regex=protected --regex
 # RUN: llvm-readelf -s %t2.o | FileCheck %s --check-prefix=PRO
 
 # PRO-DAG: PROTECTED   1 default_local
@@ -57,7 +57,7 @@
 
 
 # Check if the visibility of all symbols is properly set to INTERNAL
-# RUN: llvm-objcopy %t.o %t3.o --set-visibility-syms=%t.symbols.regex=internal --regex
+# RUN: llvm-objcopy %t.o %t3.o --set-symbols-visibility=%t.symbols.regex=internal --regex
 # RUN: llvm-readelf -s %t3.o | FileCheck %s --check-prefix=INT
 
 # INT-DAG: INTERNAL    1 default_local
@@ -77,7 +77,7 @@
 # Check if setting the visibility of certain symbols that were read from
 # a file does not affect other symbols
 # RUN: echo -e "default_local\ninternal_local" > %t.symbol.list
-# RUN: llvm-objcopy %t.o %t3.o --set-visibility-syms=%t.symbol.list=hidden
+# RUN: llvm-objcopy %t.o %t3.o --set-symbols-visibility=%t.symbol.list=hidden
 # RUN: llvm-readelf -s %t3.o | FileCheck %s --check-prefix=FILE
 
 # FILE-DAG: HIDDEN      1 default_local
diff --git a/llvm/test/tools/llvm-objcopy/ELF/set-visibility-undef-symbol.test b/llvm/test/tools/llvm-objcopy/ELF/set-visibility-undef-symbol.test
index e7a22a09351b3a..c66cff5d90f1bd 100644
--- a/llvm/test/tools/llvm-objcopy/ELF/set-visibility-undef-symbol.test
+++ b/llvm/test/tools/llvm-objcopy/ELF/set-visibility-undef-symbol.test
@@ -2,7 +2,7 @@
 # Check if symbols with SHN_UNDEF index are ignored when setting visibility
 
 # RUN: yaml2obj %s -o %t.o
-# RUN: llvm-objcopy %t.o --set-visibility-sym=foo=hidden
+# RUN: llvm-objcopy %t.o --set-symbol-visibility=foo=hidden
 # RUN: llvm-readelf -s %t.o | FileCheck %s
 
 # CHECK: DEFAULT   UND foo
diff --git a/llvm/test/tools/llvm-objcopy/ELF/set-visibility.test b/llvm/test/tools/llvm-objcopy/ELF/set-visibility.test
deleted file mode 100644
index 008981b0e06c77..00000000000000
--- a/llvm/test/tools/llvm-objcopy/ELF/set-visibility.test
+++ /dev/null
@@ -1,139 +0,0 @@
-
-# RUN: yaml2obj %s -o %t.o
-# RUN: echo '.*' > %t.symbols.regex
-
-# RUN: cp %t.o %t0.o
-# RUN: llvm-objcopy %t0.o --set-visibility-syms=%t.symbols.regex=default --regex
-# RUN: llvm-readelf -s %t0.o | FileCheck %s --check-prefix=DEF
-# DEF-DAG: LOCAL  DEFAULT     1 default_local
-# DEF-DAG: LOCAL  DEFAULT     1 internal_local
-# DEF-DAG: LOCAL  DEFAULT     1 hidden_local
-# DEF-DAG: LOCAL  DEFAULT     1 protected_local
-# DEF-DAG: GLOBAL DEFAULT     1 default_global
-# DEF-DAG: WEAK   DEFAULT     1 default_weak
-# DEF-DAG: GLOBAL DEFAULT     1 internal_global
-# DEF-DAG: WEAK   DEFAULT     1 internal_weak
-# DEF-DAG: GLOBAL DEFAULT     1 hidden_global
-# DEF-DAG: WEAK   DEFAULT     1 hidden_weak
-# DEF-DAG: GLOBAL DEFAULT     1 protected_global
-# DEF-DAG: WEAK   DEFAULT     1 protected_weak
-
-# RUN: cp %t.o %t0.o
-# RUN: llvm-objcopy %t0.o --set-visibility-syms=%t.symbols.regex=hidden --regex
-# RUN: llvm-readelf -s %t0.o | FileCheck %s --check-prefix=HID
-# HID-DAG: LOCAL  HIDDEN      1 default_local
-# HID-DAG: LOCAL  HIDDEN      1 internal_local
-# HID-DAG: LOCAL  HIDDEN      1 hidden_local
-# HID-DAG: LOCAL  HIDDEN      1 protected_local
-# HID-DAG: GLOBAL HIDDEN      1 default_global
-# HID-DAG: WEAK   HIDDEN      1 default_weak
-# HID-DAG: GLOBAL HIDDEN      1 internal_global
-# HID-DAG: WEAK   HIDDEN      1 internal_weak
-# HID-DAG: GLOBAL HIDDEN      1 hidden_global
-# HID-DAG: WEAK   HIDDEN      1 hidden_weak
-# HID-DAG: GLOBAL HIDDEN      1 protected_global
-# HID-DAG: WEAK   HIDDEN      1 protected_weak
-
-# RUN: cp %t.o %t0.o
-# RUN: llvm-objcopy %t0.o --set-visibility-syms=%t.symbols.regex=protected --regex
-# RUN: llvm-readelf -s %t0.o | FileCheck %s --check-prefix=PRO
-# PRO-DAG: LOCAL  PROTECTED   1 default_local
-# PRO-DAG: LOCAL  PROTECTED   1 internal_local
-# PRO-DAG: LOCAL  PROTECTED   1 hidden_local
-# PRO-DAG: LOCAL  PROTECTED   1 protected_local
-# PRO-DAG: GLOBAL PROTECTED   1 default_global
-# PRO-DAG: WEAK   PROTECTED   1 default_weak
-# PRO-DAG: GLOBAL PROTECTED   1 internal_global
-# PRO-DAG: WEAK   PROTECTED   1 internal_weak
-# PRO-DAG: GLOBAL PROTECTED   1 hidden_global
-# PRO-DAG: WEAK   PROTECTED   1 hidden_weak
-# PRO-DAG: GLOBAL PROTECTED   1 protected_global
-# PRO-DAG: WEAK   PROTECTED   1 protected_weak
-
-# RUN: cp %t.o %t0.o
-# RUN: llvm-objcopy %t0.o --set-visibility-syms=%t.symbols.regex=internal --regex
-# RUN: llvm-readelf -s %t0.o | FileCheck %s --check-prefix=INT
-# INT-DAG: LOCAL  INTERNAL    1 default_local
-# INT-DAG: LOCAL  INTERNAL    1 internal_local
-# INT-DAG: LOCAL  INTERNAL    1 hidden_local
-# INT-DAG: LOCAL  INTERNAL    1 protected_local
-# INT-DAG: GLOBAL INTERNAL    1 default_global
-# INT-DAG: WEAK   INTERNAL    1 default_weak
-# INT-DAG: GLOBAL INTERNAL    1 internal_global
-# INT-DAG: WEAK   INTERNAL    1 internal_weak
-# INT-DAG: GLOBAL INTERNAL    1 hidden_global
-# INT-DAG: WEAK   INTERNAL    1 hidden_weak
-# INT-DAG: GLOBAL INTERNAL    1 protected_global
-# INT-DAG: WEAK   INTERNAL    1 protected_weak
-
-# RUN: cp %t.o %t0.o
-# RUN: llvm-objcopy %t0.o --set-visibility-sym=hidden_global=default
-# RUN: llvm-objcopy %t0.o --set-visibility-sym=default_global=hidden
-# RUN: llvm-objcopy %t0.o --set-visibility-sym=internal_global=protected
-# RUN: llvm-objcopy %t0.o --set-visibility-sym=protected_global=internal
-# RUN: llvm-readelf -s %t0.o | FileCheck %s --check-prefix=SYM
-# SYM-DAG: GLOBAL DEFAULT     1 hidden_global
-# SYM-DAG: GLOBAL HIDDEN      1 default_global
-# SYM-DAG: GLOBAL PROTECTED   1 internal_global
-# SYM-DAG: GLOBAL INTERNAL    1 protected_global
-
-!ELF
-FileHeader:
-  Class:           ELFCLASS64
-  Data:            ELFDATA2LSB
-  Type:            ET_REL
-  Machine:         EM_X86_64
-Sections:
-  - Name:            .text
-    Type:            SHT_PROGBITS
-    Flags:           [ SHF_ALLOC, SHF_EXECINSTR ]
-Symbols:
-  - Name:    default_local
-    Section: .text
-    Binding:  STB_LOCAL
-  - Name:    default_global
-    Section: .text
-    Binding:  STB_GLOBAL
-  - Name:    default_weak
-    Section: .text
-    Binding:  STB_WEAK
-  - Name:    internal_local
-    Section: .text
-    Binding:  STB_LOCAL
-    Other:    [ STV_INTERNAL ]
-  - Name:    internal_global
-    Section: .text
-    Binding:  STB_GLOBAL
-    Other:    [ STV_INTERNAL ]
-  - Name:    internal_weak
-    Section: .text
-    Binding:  STB_WEAK
-    Other:    [ STV_INTERNAL ]
-  - Name:    hidden_local
-    Section: .text
-    Binding:  STB_LOCAL
-    Other:    [ STV_HIDDEN ]
-  - Name:    hidden_global
-    Section: .text
-    Binding:  STB_GLOBAL
-    Other:    [ STV_HIDDEN ]
-  - Name:    hidden_weak
-    Section: .text
-    Binding:  STB_WEAK
-    Other:    [ STV_HIDDEN ]
-  - Name:    protected_local
-    Section: .text
-    Binding:  STB_LOCAL
-    Other:    [ STV_PROTECTED ]
-  - Name:    protected_global
-    Section: .text
-    Binding:  STB_GLOBAL
-    Other:    [ STV_PROTECTED ]
-  - Name:    protected_weak
-    Section: .text
-    Binding:  STB_WEAK
-    Other:    [ STV_PROTECTED ]
-  - Name:    ignored_name
-    Section: .text
-    Binding:  STB_GLOBAL
-    Other:    [ STV_INTERNAL ]
diff --git a/llvm/tools/llvm-objcopy/ObjcopyOptions.cpp b/llvm/tools/llvm-objcopy/ObjcopyOptions.cpp
index a6f8c8cf7b48ef..d682b7233c07ef 100644
--- a/llvm/tools/llvm-objcopy/ObjcopyOptions.cpp
+++ b/llvm/tools/llvm-objcopy/ObjcopyOptions.cpp
@@ -977,13 +977,13 @@ objcopy::parseObjcopyOptions(ArrayRef<const char *> RawArgsArr,
 
     Config.SymbolsToAdd.push_back(*SymInfo);
   }
-  for (auto *Arg : InputArgs.filtered(OBJCOPY_set_visibility_sym)) {
+  for (auto *Arg : InputArgs.filtered(OBJCOPY_set_symbol_visibility)) {
     if (!ELFConfig.SymbolsToSetVisibility.empty())
       return createStringError(errc::invalid_argument,
                                "multiple specifications of visibility type");
     if (!StringRef(Arg->getValue()).contains('='))
       return createStringError(errc::invalid_argument,
-                               "bad format for --set-visibility-sym");
+                               "bad format for --set-symbol-visibility");
     auto [Sym, Visibility] = StringRef(Arg->getValue()).split('=');
     Expected<uint8_t> Type = parseVisibilityType(Visibility);
     if (!Type)
@@ -994,13 +994,13 @@ objcopy::parseObjcopyOptions(ArrayRef<const char *> RawArgsArr,
                 Sym, SymbolMatchStyle, ErrorCallback)))
       return std::move(E);
   }
-  for (auto *Arg : InputArgs.filtered(OBJCOPY_set_visibility_syms)) {
+  for (auto *Arg : InputArgs.filtered(OBJCOPY_set_symbols_visibility)) {
     if (!ELFConfig.SymbolsToSetVisibility.empty())
       return createStringError(errc::invalid_argument,
                                "multiple specifications of visibility type");
     if (!StringRef(Arg->getValue()).contains('='))
       return createStringError(errc::invalid_argument,
-                               "bad format for --set-visibility-syms");
+                               "bad format for --set-symbols-visibility");
     auto [File, Visibility] = StringRef(Arg->getValue()).split('=');
     Expected<uint8_t> Type = parseVisibilityType(Visibility);
     if (!Type)
diff --git a/llvm/tools/llvm-objcopy/ObjcopyOpts.td b/llvm/tools/llvm-objcopy/ObjcopyOpts.td
index d872316df5190f..b610b4cd45670a 100644
--- a/llvm/tools/llvm-objcopy/ObjcopyOpts.td
+++ b/llvm/tools/llvm-objcopy/ObjcopyOpts.td
@@ -93,12 +93,12 @@ defm set_section_type
          "Set the type of section <section> to the integer <type>">,
       MetaVarName<"section=type">;
 
-defm set_visibility_sym
-    : Eq<"set-visibility-sym",
+defm set_symbol_visibility
+    : Eq<"set-symbol-visibility",
          "Change the visibility of a symbol to the specified type">,
       MetaVarName<"symbol=visibility_type">;
-defm set_visibility_syms
-    : Eq<"set-visibility-syms",
+defm set_symbols_visibility
+    : Eq<"set-symbols-visibility",
          "Reads a list of symbols from <filename> and changes their "
          "visibility to the specified type. Visibility types: default, "
          "internal, hidden, protected">,

>From 105e335d1cf272e7c34111cd4240c47af80add2a Mon Sep 17 00:00:00 2001
From: Ilia Kuklin <ikuklin at accesssoftek.com>
Date: Thu, 8 Feb 2024 22:57:39 +0500
Subject: [PATCH 11/24] Apply clang-format

---
 llvm/tools/llvm-objcopy/ObjcopyOptions.cpp | 8 +++-----
 1 file changed, 3 insertions(+), 5 deletions(-)

diff --git a/llvm/tools/llvm-objcopy/ObjcopyOptions.cpp b/llvm/tools/llvm-objcopy/ObjcopyOptions.cpp
index d682b7233c07ef..20529b0a95b9fe 100644
--- a/llvm/tools/llvm-objcopy/ObjcopyOptions.cpp
+++ b/llvm/tools/llvm-objcopy/ObjcopyOptions.cpp
@@ -989,9 +989,8 @@ objcopy::parseObjcopyOptions(ArrayRef<const char *> RawArgsArr,
     if (!Type)
       return Type.takeError();
     ELFConfig.SetVisibilityType = *Type;
-    if (Error E =
-            ELFConfig.SymbolsToSetVisibility.addMatcher(NameOrPattern::create(
-                Sym, SymbolMatchStyle, ErrorCallback)))
+    if (Error E = ELFConfig.SymbolsToSetVisibility.addMatcher(
+            NameOrPattern::create(Sym, SymbolMatchStyle, ErrorCallback)))
       return std::move(E);
   }
   for (auto *Arg : InputArgs.filtered(OBJCOPY_set_symbols_visibility)) {
@@ -1007,8 +1006,7 @@ objcopy::parseObjcopyOptions(ArrayRef<const char *> RawArgsArr,
       return Type.takeError();
     ELFConfig.SetVisibilityType = *Type;
     if (Error E = addSymbolsFromFile(ELFConfig.SymbolsToSetVisibility, DC.Alloc,
-                                     File, SymbolMatchStyle,
-                                     ErrorCallback))
+                                     File, SymbolMatchStyle, ErrorCallback))
       return std::move(E);
   }
 

>From cf0c1e5953ed0eb6d06ab3f82184f70c1a0f0e13 Mon Sep 17 00:00:00 2001
From: Ilia Kuklin <ikuklin at accesssoftek.com>
Date: Wed, 14 Feb 2024 21:46:00 +0500
Subject: [PATCH 12/24] Remove checks for multiple uses of setting visibility

---
 .../ELF/set-visibility-check-errors.test             | 12 ------------
 llvm/tools/llvm-objcopy/ObjcopyOptions.cpp           |  6 ------
 2 files changed, 18 deletions(-)

diff --git a/llvm/test/tools/llvm-objcopy/ELF/set-visibility-check-errors.test b/llvm/test/tools/llvm-objcopy/ELF/set-visibility-check-errors.test
index dd67a9863a089c..fcbe8adef644ae 100644
--- a/llvm/test/tools/llvm-objcopy/ELF/set-visibility-check-errors.test
+++ b/llvm/test/tools/llvm-objcopy/ELF/set-visibility-check-errors.test
@@ -7,18 +7,6 @@
 # RUN: not llvm-objcopy %t.o --set-symbol-visibility=foo=invalid-type --regex 2>&1 | FileCheck %s --check-prefix=TYPE
 # TYPE: error: 'invalid-type' is not a valid symbol visibility
 
-# Check if using the option multiple times generates an error message
-# RUN: not llvm-objcopy %t.o --set-symbols-visibility=%t.symbols=hidden \
-# RUN:                       --set-symbols-visibility=%t.symbols=default \
-# RUN:                       --regex 2>&1 | FileCheck %s --check-prefix=MULTIPLE
-# RUN: not llvm-objcopy %t.o --set-symbol-visibility=foo=hidden \
-# RUN:                       --set-symbol-visibility=bar=default \
-# RUN:                       --regex 2>&1 | FileCheck %s --check-prefix=MULTIPLE
-# RUN: not llvm-objcopy %t.o --set-symbols-visibility=%t.symbols=hidden \
-# RUN:                       --set-symbol-visibility=bar=default \
-# RUN:                       --regex 2>&1 | FileCheck %s --check-prefix=MULTIPLE
-# MULTIPLE: error: multiple specifications of visibility type
-
 # Check if not using the proper format with character '=' generates an error
 # RUN: not llvm-objcopy %t.o --set-symbols-visibility=%t.symbols,hidden 2>&1 | FileCheck %s --check-prefix=FORMAT
 # RUN: not llvm-objcopy %t.o --set-symbol-visibility=foo default 2>&1 | FileCheck %s --check-prefix=FORMAT
diff --git a/llvm/tools/llvm-objcopy/ObjcopyOptions.cpp b/llvm/tools/llvm-objcopy/ObjcopyOptions.cpp
index 20529b0a95b9fe..5a7ea5ab10f2c2 100644
--- a/llvm/tools/llvm-objcopy/ObjcopyOptions.cpp
+++ b/llvm/tools/llvm-objcopy/ObjcopyOptions.cpp
@@ -978,9 +978,6 @@ objcopy::parseObjcopyOptions(ArrayRef<const char *> RawArgsArr,
     Config.SymbolsToAdd.push_back(*SymInfo);
   }
   for (auto *Arg : InputArgs.filtered(OBJCOPY_set_symbol_visibility)) {
-    if (!ELFConfig.SymbolsToSetVisibility.empty())
-      return createStringError(errc::invalid_argument,
-                               "multiple specifications of visibility type");
     if (!StringRef(Arg->getValue()).contains('='))
       return createStringError(errc::invalid_argument,
                                "bad format for --set-symbol-visibility");
@@ -994,9 +991,6 @@ objcopy::parseObjcopyOptions(ArrayRef<const char *> RawArgsArr,
       return std::move(E);
   }
   for (auto *Arg : InputArgs.filtered(OBJCOPY_set_symbols_visibility)) {
-    if (!ELFConfig.SymbolsToSetVisibility.empty())
-      return createStringError(errc::invalid_argument,
-                               "multiple specifications of visibility type");
     if (!StringRef(Arg->getValue()).contains('='))
       return createStringError(errc::invalid_argument,
                                "bad format for --set-symbols-visibility");

>From 88c3cf25abbce9e3631b2a06c22982b377e7183b Mon Sep 17 00:00:00 2001
From: Ilia Kuklin <ikuklin at accesssoftek.com>
Date: Wed, 14 Feb 2024 22:09:47 +0500
Subject: [PATCH 13/24] Allow each symbol pattern to have a separate visibility

---
 llvm/include/llvm/ObjCopy/ELF/ELFConfig.h             |  3 +--
 llvm/lib/ObjCopy/ELF/ELFObjcopy.cpp                   |  6 +++---
 .../tools/llvm-objcopy/ELF/set-visibility-symbol.test |  8 ++++----
 llvm/tools/llvm-objcopy/ObjcopyOptions.cpp            | 11 ++++++-----
 4 files changed, 14 insertions(+), 14 deletions(-)

diff --git a/llvm/include/llvm/ObjCopy/ELF/ELFConfig.h b/llvm/include/llvm/ObjCopy/ELF/ELFConfig.h
index b3efa3205e3766..eafed92516c7df 100644
--- a/llvm/include/llvm/ObjCopy/ELF/ELFConfig.h
+++ b/llvm/include/llvm/ObjCopy/ELF/ELFConfig.h
@@ -19,8 +19,7 @@ namespace objcopy {
 struct ELFConfig {
   uint8_t NewSymbolVisibility = (uint8_t)ELF::STV_DEFAULT;
 
-  NameMatcher SymbolsToSetVisibility;
-  uint8_t SetVisibilityType = ELF::STV_DEFAULT;
+  std::vector<std::pair<NameMatcher, uint8_t>> SymbolsToSetVisibility;
 
   // ELF entry point address expression. The input parameter is an entry point
   // address in the input ELF file. The entry address in the output file is
diff --git a/llvm/lib/ObjCopy/ELF/ELFObjcopy.cpp b/llvm/lib/ObjCopy/ELF/ELFObjcopy.cpp
index 500306c5b70476..dd03db3fe9171b 100644
--- a/llvm/lib/ObjCopy/ELF/ELFObjcopy.cpp
+++ b/llvm/lib/ObjCopy/ELF/ELFObjcopy.cpp
@@ -298,9 +298,9 @@ static Error updateAndRemoveSymbols(const CommonConfig &Config,
          Config.SymbolsToLocalize.matches(Sym.Name)))
       Sym.Binding = STB_LOCAL;
 
-    if (ELFConfig.SymbolsToSetVisibility.matches(Sym.Name) &&
-        Sym.getShndx() != SHN_UNDEF)
-      Sym.Visibility = ELFConfig.SetVisibilityType;
+    for (auto &[Matcher, VisibilityType] : ELFConfig.SymbolsToSetVisibility)
+      if (Matcher.matches(Sym.Name) && Sym.getShndx() != SHN_UNDEF)
+        Sym.Visibility = VisibilityType;
 
     // Note: these two globalize flags have very similar names but different
     // meanings:
diff --git a/llvm/test/tools/llvm-objcopy/ELF/set-visibility-symbol.test b/llvm/test/tools/llvm-objcopy/ELF/set-visibility-symbol.test
index 6b6588d2ed3fff..dc4b7d81022772 100644
--- a/llvm/test/tools/llvm-objcopy/ELF/set-visibility-symbol.test
+++ b/llvm/test/tools/llvm-objcopy/ELF/set-visibility-symbol.test
@@ -4,10 +4,10 @@
 # Check if the visibility of a single symbol is set correctly,
 # and none of other symbols are affected
 # RUN: cp %t.o %t0.o
-# RUN: llvm-objcopy %t0.o --set-symbol-visibility=default_local=hidden
-# RUN: llvm-objcopy %t0.o --set-symbol-visibility=internal_local=protected
-# RUN: llvm-objcopy %t0.o --set-symbol-visibility=hidden_local=internal
-# RUN: llvm-objcopy %t0.o --set-symbol-visibility=protected_local=default
+# RUN: llvm-objcopy %t0.o --set-symbol-visibility=default_local=hidden \
+# RUN:                    --set-symbol-visibility=internal_local=protected \
+# RUN:                    --set-symbol-visibility=hidden_local=internal \
+# RUN:                    --set-symbol-visibility=protected_local=default
 # RUN: llvm-readelf -s %t0.o | FileCheck %s --check-prefix=SINGLE
 
 # SINGLE-DAG: HIDDEN      1 default_local
diff --git a/llvm/tools/llvm-objcopy/ObjcopyOptions.cpp b/llvm/tools/llvm-objcopy/ObjcopyOptions.cpp
index 5a7ea5ab10f2c2..fc8086e451625b 100644
--- a/llvm/tools/llvm-objcopy/ObjcopyOptions.cpp
+++ b/llvm/tools/llvm-objcopy/ObjcopyOptions.cpp
@@ -985,8 +985,8 @@ objcopy::parseObjcopyOptions(ArrayRef<const char *> RawArgsArr,
     Expected<uint8_t> Type = parseVisibilityType(Visibility);
     if (!Type)
       return Type.takeError();
-    ELFConfig.SetVisibilityType = *Type;
-    if (Error E = ELFConfig.SymbolsToSetVisibility.addMatcher(
+    ELFConfig.SymbolsToSetVisibility.emplace_back(NameMatcher(), *Type);
+    if (Error E = ELFConfig.SymbolsToSetVisibility.back().first.addMatcher(
             NameOrPattern::create(Sym, SymbolMatchStyle, ErrorCallback)))
       return std::move(E);
   }
@@ -998,9 +998,10 @@ objcopy::parseObjcopyOptions(ArrayRef<const char *> RawArgsArr,
     Expected<uint8_t> Type = parseVisibilityType(Visibility);
     if (!Type)
       return Type.takeError();
-    ELFConfig.SetVisibilityType = *Type;
-    if (Error E = addSymbolsFromFile(ELFConfig.SymbolsToSetVisibility, DC.Alloc,
-                                     File, SymbolMatchStyle, ErrorCallback))
+    ELFConfig.SymbolsToSetVisibility.emplace_back(NameMatcher(), *Type);
+    if (Error E =
+            addSymbolsFromFile(ELFConfig.SymbolsToSetVisibility.back().first,
+                               DC.Alloc, File, SymbolMatchStyle, ErrorCallback))
       return std::move(E);
   }
 

>From 78cd4965e434b1179a1982e111c71e1c1d556a4f Mon Sep 17 00:00:00 2001
From: Ilia Kuklin <ikuklin at accesssoftek.com>
Date: Thu, 15 Feb 2024 20:37:20 +0500
Subject: [PATCH 14/24] Adjust formatting and wording in tests

---
 .../ELF/set-visibility-check-errors.test      | 39 +++++++++++--------
 .../ELF/set-visibility-symbol.test            | 27 ++++++-------
 .../ELF/set-visibility-symbols.test           | 29 ++++++--------
 .../ELF/set-visibility-undef-symbol.test      | 13 +++----
 4 files changed, 51 insertions(+), 57 deletions(-)

diff --git a/llvm/test/tools/llvm-objcopy/ELF/set-visibility-check-errors.test b/llvm/test/tools/llvm-objcopy/ELF/set-visibility-check-errors.test
index fcbe8adef644ae..fbeb8a904d712a 100644
--- a/llvm/test/tools/llvm-objcopy/ELF/set-visibility-check-errors.test
+++ b/llvm/test/tools/llvm-objcopy/ELF/set-visibility-check-errors.test
@@ -1,31 +1,36 @@
-
 # RUN: yaml2obj %s -o %t.o
 # RUN: echo 'foo' > %t.symbols
 
-# Check if passing an invalid visibility type generates an error message
-# RUN: not llvm-objcopy %t.o --set-symbols-visibility=%t.symbols=invalid-type --regex 2>&1 | FileCheck %s --check-prefix=TYPE
-# RUN: not llvm-objcopy %t.o --set-symbol-visibility=foo=invalid-type --regex 2>&1 | FileCheck %s --check-prefix=TYPE
+## Check that passing an invalid visibility type generates an error message
+# RUN: not llvm-objcopy %t.o --set-symbols-visibility=%t.symbols=invalid-type --regex 2>&1 | \
+# RUN:   FileCheck %s --check-prefix=TYPE
+# RUN: not llvm-objcopy %t.o --set-symbol-visibility=foo=invalid-type --regex 2>&1 | \
+# RUN:   FileCheck %s --check-prefix=TYPE
 # TYPE: error: 'invalid-type' is not a valid symbol visibility
 
-# Check if not using the proper format with character '=' generates an error
-# RUN: not llvm-objcopy %t.o --set-symbols-visibility=%t.symbols,hidden 2>&1 | FileCheck %s --check-prefix=FORMAT
-# RUN: not llvm-objcopy %t.o --set-symbol-visibility=foo default 2>&1 | FileCheck %s --check-prefix=FORMAT
+## Check that omitting the '=' character generates an error
+# RUN: not llvm-objcopy %t.o --set-symbols-visibility=%t.symbols,hidden 2>&1 | \
+# RUN:   FileCheck %s --check-prefix=FORMAT
+# RUN: not llvm-objcopy %t.o --set-symbol-visibility=foo default 2>&1 | \
+# RUN:   FileCheck %s --check-prefix=FORMAT
 # FORMAT: error: bad format for --set-symbol{{.?}}-visibility
 
-# Check if using an invalid symbol pattern generates an error
+## Check that using an invalid symbol pattern generates an error
 # RUN: echo '*.' > %t.symbols.regex
-# RUN: not llvm-objcopy %t.o --set-symbols-visibility=%t.symbols.regex=hidden --regex 2>&1 | FileCheck %s --check-prefix=SYMBOL
-# RUN: not llvm-objcopy %t.o --set-symbol-visibility=*.=default --regex 2>&1 | FileCheck %s --check-prefix=SYMBOL
+# RUN: not llvm-objcopy %t.o --set-symbols-visibility=%t.symbols.regex=hidden --regex 2>&1 | \
+# RUN:   FileCheck %s --check-prefix=SYMBOL
+# RUN: not llvm-objcopy %t.o --set-symbol-visibility=*.=default --regex 2>&1 | \
+# RUN:   FileCheck %s --check-prefix=SYMBOL
 # SYMBOL: error: cannot compile regular expression '*.': repetition-operator operand invalid
 
-# Check passing an invalid filename generates an error
-# RUN: not llvm-objcopy %t.o --set-symbols-visibility=no_file=hidden 2>&1 | FileCheck %s --check-prefix=FILE
+## Check passing an invalid filename generates an error
+# RUN: not llvm-objcopy %t.o --set-symbols-visibility=no_file=hidden 2>&1 | \
+# RUN:   FileCheck %s --check-prefix=FILE
 # FILE: error: 'no_file': No such file or directory
 
-
 !ELF
 FileHeader:
-  Class:           ELFCLASS64
-  Data:            ELFDATA2LSB
-  Type:            ET_REL
-  Machine:         EM_X86_64
+  Class:   ELFCLASS64
+  Data:    ELFDATA2LSB
+  Type:    ET_REL
+  Machine: EM_X86_64
diff --git a/llvm/test/tools/llvm-objcopy/ELF/set-visibility-symbol.test b/llvm/test/tools/llvm-objcopy/ELF/set-visibility-symbol.test
index dc4b7d81022772..272a5b59618837 100644
--- a/llvm/test/tools/llvm-objcopy/ELF/set-visibility-symbol.test
+++ b/llvm/test/tools/llvm-objcopy/ELF/set-visibility-symbol.test
@@ -1,8 +1,7 @@
-
 # RUN: yaml2obj %s -o %t.o
 
-# Check if the visibility of a single symbol is set correctly,
-# and none of other symbols are affected
+## Check that the visibility of a single symbol is set correctly,
+# and that no other symbols are affected
 # RUN: cp %t.o %t0.o
 # RUN: llvm-objcopy %t0.o --set-symbol-visibility=default_local=hidden \
 # RUN:                    --set-symbol-visibility=internal_local=protected \
@@ -14,7 +13,7 @@
 # SINGLE-DAG: PROTECTED   1 internal_local
 # SINGLE-DAG: INTERNAL    1 hidden_local
 # SINGLE-DAG: DEFAULT     1 protected_local
-# Unaffected symbols:
+## Unaffected symbols:
 # SINGLE-DAG: DEFAULT     1 default_global
 # SINGLE-DAG: DEFAULT     1 default_weak
 # SINGLE-DAG: INTERNAL    1 internal_global
@@ -24,9 +23,8 @@
 # SINGLE-DAG: PROTECTED   1 protected_global
 # SINGLE-DAG: PROTECTED   1 protected_weak
 
-
-# Check if the visibility of symbols specified by a regex are set correctly,
-# and none of other symbols are affected
+## Check that the visibility of symbols specified by a regex are set correctly,
+# and that no other symbols are affected
 # RUN: llvm-objcopy %t.o %t1.o --set-symbol-visibility=.*_local=hidden --regex
 # RUN: llvm-readelf -s %t1.o | FileCheck %s --check-prefix=REGEX
 
@@ -34,7 +32,7 @@
 # REGEX-DAG: HIDDEN      1 internal_local
 # REGEX-DAG: HIDDEN      1 hidden_local
 # REGEX-DAG: HIDDEN      1 protected_local
-# Unaffected symbols:
+## Unaffected symbols:
 # REGEX-DAG: DEFAULT     1 default_global
 # REGEX-DAG: DEFAULT     1 default_weak
 # REGEX-DAG: INTERNAL    1 internal_global
@@ -44,16 +42,15 @@
 # REGEX-DAG: PROTECTED   1 protected_global
 # REGEX-DAG: PROTECTED   1 protected_weak
 
-
 !ELF
 FileHeader:
-  Class:           ELFCLASS64
-  Data:            ELFDATA2LSB
-  Type:            ET_REL
-  Machine:         EM_X86_64
+  Class:   ELFCLASS64
+  Data:    ELFDATA2LSB
+  Type:    ET_REL
+  Machine: EM_X86_64
 Sections:
-  - Name:            .text
-    Type:            SHT_PROGBITS
+  - Name:  .text
+    Type:  SHT_PROGBITS
 Symbols:
   - Name:    default_local
     Section: .text
diff --git a/llvm/test/tools/llvm-objcopy/ELF/set-visibility-symbols.test b/llvm/test/tools/llvm-objcopy/ELF/set-visibility-symbols.test
index 99c417f76304da..9d27c35fb1b73d 100644
--- a/llvm/test/tools/llvm-objcopy/ELF/set-visibility-symbols.test
+++ b/llvm/test/tools/llvm-objcopy/ELF/set-visibility-symbols.test
@@ -1,8 +1,7 @@
-
 # RUN: yaml2obj %s -o %t.o
 # RUN: echo '.*' > %t.symbols.regex
 
-# Check if the visibility of all symbols is properly set to DEFAULT
+## Check that the visibility of all symbols is properly set to DEFAULT
 # RUN: llvm-objcopy %t.o %t0.o --set-symbols-visibility=%t.symbols.regex=default --regex
 # RUN: llvm-readelf -s %t0.o | FileCheck %s --check-prefix=DEF
 
@@ -19,8 +18,7 @@
 # DEF-DAG: DEFAULT     1 protected_global
 # DEF-DAG: DEFAULT     1 protected_weak
 
-
-# Check if the visibility of all symbols is properly set to HIDDEN
+## Check that the visibility of all symbols is properly set to HIDDEN
 # RUN: llvm-objcopy %t.o %t1.o --set-symbols-visibility=%t.symbols.regex=hidden --regex
 # RUN: llvm-readelf -s %t1.o | FileCheck %s --check-prefix=HID
 
@@ -37,8 +35,7 @@
 # HID-DAG: HIDDEN      1 protected_global
 # HID-DAG: HIDDEN      1 protected_weak
 
-
-# Check if the visibility of all symbols is properly set to PROTECTED
+## Check that the visibility of all symbols is properly set to PROTECTED
 # RUN: llvm-objcopy %t.o %t2.o --set-symbols-visibility=%t.symbols.regex=protected --regex
 # RUN: llvm-readelf -s %t2.o | FileCheck %s --check-prefix=PRO
 
@@ -55,8 +52,7 @@
 # PRO-DAG: PROTECTED   1 protected_global
 # PRO-DAG: PROTECTED   1 protected_weak
 
-
-# Check if the visibility of all symbols is properly set to INTERNAL
+## Check that the visibility of all symbols is properly set to INTERNAL
 # RUN: llvm-objcopy %t.o %t3.o --set-symbols-visibility=%t.symbols.regex=internal --regex
 # RUN: llvm-readelf -s %t3.o | FileCheck %s --check-prefix=INT
 
@@ -73,8 +69,7 @@
 # INT-DAG: INTERNAL    1 protected_global
 # INT-DAG: INTERNAL    1 protected_weak
 
-
-# Check if setting the visibility of certain symbols that were read from
+## Check that setting the visibility of certain symbols that were read from
 # a file does not affect other symbols
 # RUN: echo -e "default_local\ninternal_local" > %t.symbol.list
 # RUN: llvm-objcopy %t.o %t3.o --set-symbols-visibility=%t.symbol.list=hidden
@@ -82,7 +77,7 @@
 
 # FILE-DAG: HIDDEN      1 default_local
 # FILE-DAG: HIDDEN      1 internal_local
-# Unaffected symbols:
+## Unaffected symbols:
 # FILE-DAG: HIDDEN      1 hidden_local
 # FILE-DAG: PROTECTED   1 protected_local
 # FILE-DAG: DEFAULT     1 default_global
@@ -96,13 +91,13 @@
 
 !ELF
 FileHeader:
-  Class:           ELFCLASS64
-  Data:            ELFDATA2LSB
-  Type:            ET_REL
-  Machine:         EM_X86_64
+  Class:   ELFCLASS64
+  Data:    ELFDATA2LSB
+  Type:    ET_REL
+  Machine: EM_X86_64
 Sections:
-  - Name:            .text
-    Type:            SHT_PROGBITS
+  - Name:  .text
+    Type:  SHT_PROGBITS
 Symbols:
   - Name:    default_local
     Section: .text
diff --git a/llvm/test/tools/llvm-objcopy/ELF/set-visibility-undef-symbol.test b/llvm/test/tools/llvm-objcopy/ELF/set-visibility-undef-symbol.test
index c66cff5d90f1bd..98016353e42dcf 100644
--- a/llvm/test/tools/llvm-objcopy/ELF/set-visibility-undef-symbol.test
+++ b/llvm/test/tools/llvm-objcopy/ELF/set-visibility-undef-symbol.test
@@ -1,18 +1,15 @@
-
-# Check if symbols with SHN_UNDEF index are ignored when setting visibility
-
+## Check that symbols with SHN_UNDEF index are ignored when setting visibility
 # RUN: yaml2obj %s -o %t.o
 # RUN: llvm-objcopy %t.o --set-symbol-visibility=foo=hidden
 # RUN: llvm-readelf -s %t.o | FileCheck %s
-
 # CHECK: DEFAULT   UND foo
 
 !ELF
 FileHeader:
-  Class:           ELFCLASS64
-  Data:            ELFDATA2LSB
-  Type:            ET_REL
-  Machine:         EM_X86_64
+  Class:   ELFCLASS64
+  Data:    ELFDATA2LSB
+  Type:    ET_REL
+  Machine: EM_X86_64
 Symbols:
   - Name:     foo
     Binding:  STB_LOCAL

>From 4ab67a1e945ad72ab1453b6aa2c34939631b32a9 Mon Sep 17 00:00:00 2001
From: Ilia Kuklin <ikuklin at accesssoftek.com>
Date: Thu, 15 Feb 2024 20:40:47 +0500
Subject: [PATCH 15/24] Remove unnecessary --regex option in
 set-visibility-check-errors.test

---
 .../tools/llvm-objcopy/ELF/set-visibility-check-errors.test   | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/llvm/test/tools/llvm-objcopy/ELF/set-visibility-check-errors.test b/llvm/test/tools/llvm-objcopy/ELF/set-visibility-check-errors.test
index fbeb8a904d712a..f5f49b92d2576e 100644
--- a/llvm/test/tools/llvm-objcopy/ELF/set-visibility-check-errors.test
+++ b/llvm/test/tools/llvm-objcopy/ELF/set-visibility-check-errors.test
@@ -2,9 +2,9 @@
 # RUN: echo 'foo' > %t.symbols
 
 ## Check that passing an invalid visibility type generates an error message
-# RUN: not llvm-objcopy %t.o --set-symbols-visibility=%t.symbols=invalid-type --regex 2>&1 | \
+# RUN: not llvm-objcopy %t.o --set-symbols-visibility=%t.symbols=invalid-type 2>&1 | \
 # RUN:   FileCheck %s --check-prefix=TYPE
-# RUN: not llvm-objcopy %t.o --set-symbol-visibility=foo=invalid-type --regex 2>&1 | \
+# RUN: not llvm-objcopy %t.o --set-symbol-visibility=foo=invalid-type 2>&1 | \
 # RUN:   FileCheck %s --check-prefix=TYPE
 # TYPE: error: 'invalid-type' is not a valid symbol visibility
 

>From 17f6c404bfb27e3746a336eed63a0a87dca0fd72 Mon Sep 17 00:00:00 2001
From: Ilia Kuklin <ikuklin at accesssoftek.com>
Date: Thu, 15 Feb 2024 20:58:10 +0500
Subject: [PATCH 16/24] Explicitly check the option name in
 set-visibility-check-errors.test

---
 .../tools/llvm-objcopy/ELF/set-visibility-check-errors.test | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/llvm/test/tools/llvm-objcopy/ELF/set-visibility-check-errors.test b/llvm/test/tools/llvm-objcopy/ELF/set-visibility-check-errors.test
index f5f49b92d2576e..cdd31e5c153fe1 100644
--- a/llvm/test/tools/llvm-objcopy/ELF/set-visibility-check-errors.test
+++ b/llvm/test/tools/llvm-objcopy/ELF/set-visibility-check-errors.test
@@ -10,10 +10,10 @@
 
 ## Check that omitting the '=' character generates an error
 # RUN: not llvm-objcopy %t.o --set-symbols-visibility=%t.symbols,hidden 2>&1 | \
-# RUN:   FileCheck %s --check-prefix=FORMAT
+# RUN:   FileCheck %s --check-prefix=FORMAT -DOPTION=--set-symbols-visibility
 # RUN: not llvm-objcopy %t.o --set-symbol-visibility=foo default 2>&1 | \
-# RUN:   FileCheck %s --check-prefix=FORMAT
-# FORMAT: error: bad format for --set-symbol{{.?}}-visibility
+# RUN:   FileCheck %s --check-prefix=FORMAT -DOPTION=--set-symbol-visibility
+# FORMAT: error: bad format for [[OPTION]]
 
 ## Check that using an invalid symbol pattern generates an error
 # RUN: echo '*.' > %t.symbols.regex

>From 0b282803085365d33a830846d6cd9900c3398af2 Mon Sep 17 00:00:00 2001
From: Ilia Kuklin <ikuklin at accesssoftek.com>
Date: Thu, 15 Feb 2024 21:06:12 +0500
Subject: [PATCH 17/24] Use %errc_ENOENT for 'No such file or directory'
 message

---
 .../tools/llvm-objcopy/ELF/set-visibility-check-errors.test   | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/llvm/test/tools/llvm-objcopy/ELF/set-visibility-check-errors.test b/llvm/test/tools/llvm-objcopy/ELF/set-visibility-check-errors.test
index cdd31e5c153fe1..42855333cf5aed 100644
--- a/llvm/test/tools/llvm-objcopy/ELF/set-visibility-check-errors.test
+++ b/llvm/test/tools/llvm-objcopy/ELF/set-visibility-check-errors.test
@@ -25,8 +25,8 @@
 
 ## Check passing an invalid filename generates an error
 # RUN: not llvm-objcopy %t.o --set-symbols-visibility=no_file=hidden 2>&1 | \
-# RUN:   FileCheck %s --check-prefix=FILE
-# FILE: error: 'no_file': No such file or directory
+# RUN:   FileCheck %s --check-prefix=FILE -DMSG=%errc_ENOENT
+# FILE: error: 'no_file': [[MSG]]
 
 !ELF
 FileHeader:

>From 62a8bac968adb5705edb710c3ecbd71924c997b9 Mon Sep 17 00:00:00 2001
From: Ilia Kuklin <ikuklin at accesssoftek.com>
Date: Thu, 15 Feb 2024 21:11:47 +0500
Subject: [PATCH 18/24] Add a test case that uses a wildcard

---
 .../ELF/set-visibility-symbol.test            | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

diff --git a/llvm/test/tools/llvm-objcopy/ELF/set-visibility-symbol.test b/llvm/test/tools/llvm-objcopy/ELF/set-visibility-symbol.test
index 272a5b59618837..b26bead95e8f0b 100644
--- a/llvm/test/tools/llvm-objcopy/ELF/set-visibility-symbol.test
+++ b/llvm/test/tools/llvm-objcopy/ELF/set-visibility-symbol.test
@@ -42,6 +42,25 @@
 # REGEX-DAG: PROTECTED   1 protected_global
 # REGEX-DAG: PROTECTED   1 protected_weak
 
+## Check that the visibility of symbols specified by a wildcard are set correctly,
+# and that no other symbols are affected
+# RUN: llvm-objcopy %t.o %t1.o --set-symbol-visibility=*_local=hidden --wildcard
+# RUN: llvm-readelf -s %t1.o | FileCheck %s --check-prefix=WILDCARD
+
+# WILDCARD-DAG: HIDDEN      1 default_local
+# WILDCARD-DAG: HIDDEN      1 internal_local
+# WILDCARD-DAG: HIDDEN      1 hidden_local
+# WILDCARD-DAG: HIDDEN      1 protected_local
+## Unaffected symbols:
+# WILDCARD-DAG: DEFAULT     1 default_global
+# WILDCARD-DAG: DEFAULT     1 default_weak
+# WILDCARD-DAG: INTERNAL    1 internal_global
+# WILDCARD-DAG: INTERNAL    1 internal_weak
+# WILDCARD-DAG: HIDDEN      1 hidden_global
+# WILDCARD-DAG: HIDDEN      1 hidden_weak
+# WILDCARD-DAG: PROTECTED   1 protected_global
+# WILDCARD-DAG: PROTECTED   1 protected_weak
+
 !ELF
 FileHeader:
   Class:   ELFCLASS64

>From 4f7a5cd3c641492fd57b8ac201ba7453337fe0da Mon Sep 17 00:00:00 2001
From: Ilia Kuklin <ikuklin at accesssoftek.com>
Date: Thu, 15 Feb 2024 21:17:37 +0500
Subject: [PATCH 19/24] Remove unnecessary SHN_UNDEF in
 set-visibility-undef-symbol.test

---
 .../test/tools/llvm-objcopy/ELF/set-visibility-undef-symbol.test | 1 -
 1 file changed, 1 deletion(-)

diff --git a/llvm/test/tools/llvm-objcopy/ELF/set-visibility-undef-symbol.test b/llvm/test/tools/llvm-objcopy/ELF/set-visibility-undef-symbol.test
index 98016353e42dcf..158747ca2663f8 100644
--- a/llvm/test/tools/llvm-objcopy/ELF/set-visibility-undef-symbol.test
+++ b/llvm/test/tools/llvm-objcopy/ELF/set-visibility-undef-symbol.test
@@ -13,4 +13,3 @@ FileHeader:
 Symbols:
   - Name:     foo
     Binding:  STB_LOCAL
-    Index:    SHN_UNDEF

>From ed84dfdbee5b76a14983944e351c02e2b99c5597 Mon Sep 17 00:00:00 2001
From: Ilia Kuklin <ikuklin at accesssoftek.com>
Date: Fri, 16 Feb 2024 16:56:02 +0500
Subject: [PATCH 20/24] Merge 2 functionality tests into one; rename test files

---
 ...> set-symbol-visibility-check-errors.test} |   0
 ...> set-symbol-visibility-undef-symbol.test} |   0
 ...ymbols.test => set-symbol-visibility.test} |  64 ++++++++-
 .../ELF/set-visibility-symbol.test            | 122 ------------------
 4 files changed, 62 insertions(+), 124 deletions(-)
 rename llvm/test/tools/llvm-objcopy/ELF/{set-visibility-check-errors.test => set-symbol-visibility-check-errors.test} (100%)
 rename llvm/test/tools/llvm-objcopy/ELF/{set-visibility-undef-symbol.test => set-symbol-visibility-undef-symbol.test} (100%)
 rename llvm/test/tools/llvm-objcopy/ELF/{set-visibility-symbols.test => set-symbol-visibility.test} (64%)
 delete mode 100644 llvm/test/tools/llvm-objcopy/ELF/set-visibility-symbol.test

diff --git a/llvm/test/tools/llvm-objcopy/ELF/set-visibility-check-errors.test b/llvm/test/tools/llvm-objcopy/ELF/set-symbol-visibility-check-errors.test
similarity index 100%
rename from llvm/test/tools/llvm-objcopy/ELF/set-visibility-check-errors.test
rename to llvm/test/tools/llvm-objcopy/ELF/set-symbol-visibility-check-errors.test
diff --git a/llvm/test/tools/llvm-objcopy/ELF/set-visibility-undef-symbol.test b/llvm/test/tools/llvm-objcopy/ELF/set-symbol-visibility-undef-symbol.test
similarity index 100%
rename from llvm/test/tools/llvm-objcopy/ELF/set-visibility-undef-symbol.test
rename to llvm/test/tools/llvm-objcopy/ELF/set-symbol-visibility-undef-symbol.test
diff --git a/llvm/test/tools/llvm-objcopy/ELF/set-visibility-symbols.test b/llvm/test/tools/llvm-objcopy/ELF/set-symbol-visibility.test
similarity index 64%
rename from llvm/test/tools/llvm-objcopy/ELF/set-visibility-symbols.test
rename to llvm/test/tools/llvm-objcopy/ELF/set-symbol-visibility.test
index 9d27c35fb1b73d..47624d93769e17 100644
--- a/llvm/test/tools/llvm-objcopy/ELF/set-visibility-symbols.test
+++ b/llvm/test/tools/llvm-objcopy/ELF/set-symbol-visibility.test
@@ -72,8 +72,8 @@
 ## Check that setting the visibility of certain symbols that were read from
 # a file does not affect other symbols
 # RUN: echo -e "default_local\ninternal_local" > %t.symbol.list
-# RUN: llvm-objcopy %t.o %t3.o --set-symbols-visibility=%t.symbol.list=hidden
-# RUN: llvm-readelf -s %t3.o | FileCheck %s --check-prefix=FILE
+# RUN: llvm-objcopy %t.o %t4.o --set-symbols-visibility=%t.symbol.list=hidden
+# RUN: llvm-readelf -s %t4.o | FileCheck %s --check-prefix=FILE
 
 # FILE-DAG: HIDDEN      1 default_local
 # FILE-DAG: HIDDEN      1 internal_local
@@ -89,6 +89,66 @@
 # FILE-DAG: PROTECTED   1 protected_global
 # FILE-DAG: PROTECTED   1 protected_weak
 
+## Check that the visibility of a single symbol is set correctly,
+# and that no other symbols are affected
+# RUN: llvm-objcopy %t.o %t5.o --set-symbol-visibility=default_local=hidden \
+# RUN:                         --set-symbol-visibility=internal_local=protected \
+# RUN:                         --set-symbol-visibility=hidden_local=internal \
+# RUN:                         --set-symbol-visibility=protected_local=default
+# RUN: llvm-readelf -s %t5.o | FileCheck %s --check-prefix=SINGLE
+
+# SINGLE-DAG: HIDDEN      1 default_local
+# SINGLE-DAG: PROTECTED   1 internal_local
+# SINGLE-DAG: INTERNAL    1 hidden_local
+# SINGLE-DAG: DEFAULT     1 protected_local
+## Unaffected symbols:
+# SINGLE-DAG: DEFAULT     1 default_global
+# SINGLE-DAG: DEFAULT     1 default_weak
+# SINGLE-DAG: INTERNAL    1 internal_global
+# SINGLE-DAG: INTERNAL    1 internal_weak
+# SINGLE-DAG: HIDDEN      1 hidden_global
+# SINGLE-DAG: HIDDEN      1 hidden_weak
+# SINGLE-DAG: PROTECTED   1 protected_global
+# SINGLE-DAG: PROTECTED   1 protected_weak
+
+## Check that the visibility of symbols specified by a regex are set correctly,
+# and that no other symbols are affected
+# RUN: llvm-objcopy %t.o %t6.o --set-symbol-visibility=.*_local=hidden --regex
+# RUN: llvm-readelf -s %t6.o | FileCheck %s --check-prefix=REGEX
+
+# REGEX-DAG: HIDDEN      1 default_local
+# REGEX-DAG: HIDDEN      1 internal_local
+# REGEX-DAG: HIDDEN      1 hidden_local
+# REGEX-DAG: HIDDEN      1 protected_local
+## Unaffected symbols:
+# REGEX-DAG: DEFAULT     1 default_global
+# REGEX-DAG: DEFAULT     1 default_weak
+# REGEX-DAG: INTERNAL    1 internal_global
+# REGEX-DAG: INTERNAL    1 internal_weak
+# REGEX-DAG: HIDDEN      1 hidden_global
+# REGEX-DAG: HIDDEN      1 hidden_weak
+# REGEX-DAG: PROTECTED   1 protected_global
+# REGEX-DAG: PROTECTED   1 protected_weak
+
+## Check that the visibility of symbols specified by a wildcard are set correctly,
+# and that no other symbols are affected
+# RUN: llvm-objcopy %t.o %t7.o --set-symbol-visibility=*_local=hidden --wildcard
+# RUN: llvm-readelf -s %t7.o | FileCheck %s --check-prefix=WILDCARD
+
+# WILDCARD-DAG: HIDDEN      1 default_local
+# WILDCARD-DAG: HIDDEN      1 internal_local
+# WILDCARD-DAG: HIDDEN      1 hidden_local
+# WILDCARD-DAG: HIDDEN      1 protected_local
+## Unaffected symbols:
+# WILDCARD-DAG: DEFAULT     1 default_global
+# WILDCARD-DAG: DEFAULT     1 default_weak
+# WILDCARD-DAG: INTERNAL    1 internal_global
+# WILDCARD-DAG: INTERNAL    1 internal_weak
+# WILDCARD-DAG: HIDDEN      1 hidden_global
+# WILDCARD-DAG: HIDDEN      1 hidden_weak
+# WILDCARD-DAG: PROTECTED   1 protected_global
+# WILDCARD-DAG: PROTECTED   1 protected_weak
+
 !ELF
 FileHeader:
   Class:   ELFCLASS64
diff --git a/llvm/test/tools/llvm-objcopy/ELF/set-visibility-symbol.test b/llvm/test/tools/llvm-objcopy/ELF/set-visibility-symbol.test
deleted file mode 100644
index b26bead95e8f0b..00000000000000
--- a/llvm/test/tools/llvm-objcopy/ELF/set-visibility-symbol.test
+++ /dev/null
@@ -1,122 +0,0 @@
-# RUN: yaml2obj %s -o %t.o
-
-## Check that the visibility of a single symbol is set correctly,
-# and that no other symbols are affected
-# RUN: cp %t.o %t0.o
-# RUN: llvm-objcopy %t0.o --set-symbol-visibility=default_local=hidden \
-# RUN:                    --set-symbol-visibility=internal_local=protected \
-# RUN:                    --set-symbol-visibility=hidden_local=internal \
-# RUN:                    --set-symbol-visibility=protected_local=default
-# RUN: llvm-readelf -s %t0.o | FileCheck %s --check-prefix=SINGLE
-
-# SINGLE-DAG: HIDDEN      1 default_local
-# SINGLE-DAG: PROTECTED   1 internal_local
-# SINGLE-DAG: INTERNAL    1 hidden_local
-# SINGLE-DAG: DEFAULT     1 protected_local
-## Unaffected symbols:
-# SINGLE-DAG: DEFAULT     1 default_global
-# SINGLE-DAG: DEFAULT     1 default_weak
-# SINGLE-DAG: INTERNAL    1 internal_global
-# SINGLE-DAG: INTERNAL    1 internal_weak
-# SINGLE-DAG: HIDDEN      1 hidden_global
-# SINGLE-DAG: HIDDEN      1 hidden_weak
-# SINGLE-DAG: PROTECTED   1 protected_global
-# SINGLE-DAG: PROTECTED   1 protected_weak
-
-## Check that the visibility of symbols specified by a regex are set correctly,
-# and that no other symbols are affected
-# RUN: llvm-objcopy %t.o %t1.o --set-symbol-visibility=.*_local=hidden --regex
-# RUN: llvm-readelf -s %t1.o | FileCheck %s --check-prefix=REGEX
-
-# REGEX-DAG: HIDDEN      1 default_local
-# REGEX-DAG: HIDDEN      1 internal_local
-# REGEX-DAG: HIDDEN      1 hidden_local
-# REGEX-DAG: HIDDEN      1 protected_local
-## Unaffected symbols:
-# REGEX-DAG: DEFAULT     1 default_global
-# REGEX-DAG: DEFAULT     1 default_weak
-# REGEX-DAG: INTERNAL    1 internal_global
-# REGEX-DAG: INTERNAL    1 internal_weak
-# REGEX-DAG: HIDDEN      1 hidden_global
-# REGEX-DAG: HIDDEN      1 hidden_weak
-# REGEX-DAG: PROTECTED   1 protected_global
-# REGEX-DAG: PROTECTED   1 protected_weak
-
-## Check that the visibility of symbols specified by a wildcard are set correctly,
-# and that no other symbols are affected
-# RUN: llvm-objcopy %t.o %t1.o --set-symbol-visibility=*_local=hidden --wildcard
-# RUN: llvm-readelf -s %t1.o | FileCheck %s --check-prefix=WILDCARD
-
-# WILDCARD-DAG: HIDDEN      1 default_local
-# WILDCARD-DAG: HIDDEN      1 internal_local
-# WILDCARD-DAG: HIDDEN      1 hidden_local
-# WILDCARD-DAG: HIDDEN      1 protected_local
-## Unaffected symbols:
-# WILDCARD-DAG: DEFAULT     1 default_global
-# WILDCARD-DAG: DEFAULT     1 default_weak
-# WILDCARD-DAG: INTERNAL    1 internal_global
-# WILDCARD-DAG: INTERNAL    1 internal_weak
-# WILDCARD-DAG: HIDDEN      1 hidden_global
-# WILDCARD-DAG: HIDDEN      1 hidden_weak
-# WILDCARD-DAG: PROTECTED   1 protected_global
-# WILDCARD-DAG: PROTECTED   1 protected_weak
-
-!ELF
-FileHeader:
-  Class:   ELFCLASS64
-  Data:    ELFDATA2LSB
-  Type:    ET_REL
-  Machine: EM_X86_64
-Sections:
-  - Name:  .text
-    Type:  SHT_PROGBITS
-Symbols:
-  - Name:    default_local
-    Section: .text
-    Binding:  STB_LOCAL
-  - Name:    default_global
-    Section: .text
-    Binding:  STB_GLOBAL
-  - Name:    default_weak
-    Section: .text
-    Binding:  STB_WEAK
-  - Name:    internal_local
-    Section: .text
-    Binding:  STB_LOCAL
-    Other:    [ STV_INTERNAL ]
-  - Name:    internal_global
-    Section: .text
-    Binding:  STB_GLOBAL
-    Other:    [ STV_INTERNAL ]
-  - Name:    internal_weak
-    Section: .text
-    Binding:  STB_WEAK
-    Other:    [ STV_INTERNAL ]
-  - Name:    hidden_local
-    Section: .text
-    Binding:  STB_LOCAL
-    Other:    [ STV_HIDDEN ]
-  - Name:    hidden_global
-    Section: .text
-    Binding:  STB_GLOBAL
-    Other:    [ STV_HIDDEN ]
-  - Name:    hidden_weak
-    Section: .text
-    Binding:  STB_WEAK
-    Other:    [ STV_HIDDEN ]
-  - Name:    protected_local
-    Section: .text
-    Binding:  STB_LOCAL
-    Other:    [ STV_PROTECTED ]
-  - Name:    protected_global
-    Section: .text
-    Binding:  STB_GLOBAL
-    Other:    [ STV_PROTECTED ]
-  - Name:    protected_weak
-    Section: .text
-    Binding:  STB_WEAK
-    Other:    [ STV_PROTECTED ]
-  - Name:    ignored_name
-    Section: .text
-    Binding:  STB_GLOBAL
-    Other:    [ STV_INTERNAL ]

>From 2d14e71089ef76f7ac8eabe79dc18fe3ab222ee5 Mon Sep 17 00:00:00 2001
From: Ilia Kuklin <ikuklin at accesssoftek.com>
Date: Fri, 16 Feb 2024 17:18:07 +0500
Subject: [PATCH 21/24] Add a test case with a special character without
 pattern matching

---
 .../ELF/set-symbol-visibility.test            | 33 ++++++++++++++++++-
 1 file changed, 32 insertions(+), 1 deletion(-)

diff --git a/llvm/test/tools/llvm-objcopy/ELF/set-symbol-visibility.test b/llvm/test/tools/llvm-objcopy/ELF/set-symbol-visibility.test
index 47624d93769e17..b48b72786925c2 100644
--- a/llvm/test/tools/llvm-objcopy/ELF/set-symbol-visibility.test
+++ b/llvm/test/tools/llvm-objcopy/ELF/set-symbol-visibility.test
@@ -1,4 +1,4 @@
-# RUN: yaml2obj %s -o %t.o
+# RUN: yaml2obj --docnum=1 %s -o %t.o
 # RUN: echo '.*' > %t.symbols.regex
 
 ## Check that the visibility of all symbols is properly set to DEFAULT
@@ -149,6 +149,17 @@
 # WILDCARD-DAG: PROTECTED   1 protected_global
 # WILDCARD-DAG: PROTECTED   1 protected_weak
 
+## Check that a symbol name with a special charater is treated as a plain name
+## when pattern matching options are not enabled
+# RUN: yaml2obj --docnum=2 %s -o %t8.o
+# RUN: llvm-objcopy %t8.o --set-symbol-visibility=f*o=hidden
+# RUN: llvm-readelf -s %t8.o | FileCheck %s --check-prefix=SPECIAL
+
+# SPECIAL-DAG: HIDDEN      1 f*o
+## Unaffected symbol:
+# SPECIAL-DAG: DEFAULT     1 foo
+
+---
 !ELF
 FileHeader:
   Class:   ELFCLASS64
@@ -208,3 +219,23 @@ Symbols:
     Section: .text
     Binding:  STB_GLOBAL
     Other:    [ STV_INTERNAL ]
+...
+
+---
+!ELF
+FileHeader:
+  Class:   ELFCLASS64
+  Data:    ELFDATA2LSB
+  Type:    ET_REL
+  Machine: EM_X86_64
+Sections:
+  - Name:  .text
+    Type:  SHT_PROGBITS
+Symbols:
+  - Name:    f*o
+    Section: .text
+    Binding:  STB_LOCAL
+  - Name:    foo
+    Section: .text
+    Binding:  STB_LOCAL
+...

>From 7cd45b40fdd199bf4336b120b2c931f6b8e7d497 Mon Sep 17 00:00:00 2001
From: Ilia Kuklin <ikuklin at accesssoftek.com>
Date: Fri, 16 Feb 2024 17:40:54 +0500
Subject: [PATCH 22/24] Add a test case that checks visibility overwriting with
 multiple options

---
 .../ELF/set-symbol-visibility.test            | 29 +++++++++++++++++--
 1 file changed, 26 insertions(+), 3 deletions(-)

diff --git a/llvm/test/tools/llvm-objcopy/ELF/set-symbol-visibility.test b/llvm/test/tools/llvm-objcopy/ELF/set-symbol-visibility.test
index b48b72786925c2..56c120545a36ea 100644
--- a/llvm/test/tools/llvm-objcopy/ELF/set-symbol-visibility.test
+++ b/llvm/test/tools/llvm-objcopy/ELF/set-symbol-visibility.test
@@ -149,11 +149,34 @@
 # WILDCARD-DAG: PROTECTED   1 protected_global
 # WILDCARD-DAG: PROTECTED   1 protected_weak
 
+## Check that the latest option that matches the same symbols as any of the previous
+## options overwrites the visibility of these symbols
+# RUN: echo -e "*_weak\n*_local" > %t.symbols.pattern
+# RUN: llvm-objcopy %t.o %t8.o --set-symbol-visibility=default_*=hidden \
+# RUN:                         --set-symbol-visibility=internal_*=hidden \
+# RUN:                         --set-symbols-visibility=%t.symbols.pattern=protected \
+# RUN:                         --wildcard
+# RUN: llvm-readelf -s %t8.o | FileCheck %s --check-prefix=REWRITE
+
+# REWRITE-DAG: PROTECTED   1 default_local
+# REWRITE-DAG: HIDDEN      1 default_global
+# REWRITE-DAG: PROTECTED   1 default_weak
+# REWRITE-DAG: PROTECTED   1 internal_local
+# REWRITE-DAG: HIDDEN      1 internal_global
+# REWRITE-DAG: PROTECTED   1 internal_weak
+# REWRITE-DAG: PROTECTED   1 hidden_local
+# REWRITE-DAG: PROTECTED   1 hidden_weak
+# REWRITE-DAG: PROTECTED   1 protected_local
+# REWRITE-DAG: PROTECTED   1 protected_weak
+## Unaffected symbols:
+# REWRITE-DAG: HIDDEN      1 hidden_global
+# REWRITE-DAG: PROTECTED   1 protected_global
+
 ## Check that a symbol name with a special charater is treated as a plain name
 ## when pattern matching options are not enabled
-# RUN: yaml2obj --docnum=2 %s -o %t8.o
-# RUN: llvm-objcopy %t8.o --set-symbol-visibility=f*o=hidden
-# RUN: llvm-readelf -s %t8.o | FileCheck %s --check-prefix=SPECIAL
+# RUN: yaml2obj --docnum=2 %s -o %t9.o
+# RUN: llvm-objcopy %t9.o --set-symbol-visibility=f*o=hidden
+# RUN: llvm-readelf -s %t9.o | FileCheck %s --check-prefix=SPECIAL
 
 # SPECIAL-DAG: HIDDEN      1 f*o
 ## Unaffected symbol:

>From 98e127fbd25b80668452ce5d9941a600d966f5bc Mon Sep 17 00:00:00 2001
From: Ilia Kuklin <ikuklin at accesssoftek.com>
Date: Fri, 16 Feb 2024 17:47:42 +0500
Subject: [PATCH 23/24] Adjust test formatting

---
 .../set-symbol-visibility-check-errors.test   |  8 ++++----
 .../set-symbol-visibility-undef-symbol.test   |  2 +-
 .../ELF/set-symbol-visibility.test            | 20 +++++++++----------
 3 files changed, 15 insertions(+), 15 deletions(-)

diff --git a/llvm/test/tools/llvm-objcopy/ELF/set-symbol-visibility-check-errors.test b/llvm/test/tools/llvm-objcopy/ELF/set-symbol-visibility-check-errors.test
index 42855333cf5aed..fa63b591ebc079 100644
--- a/llvm/test/tools/llvm-objcopy/ELF/set-symbol-visibility-check-errors.test
+++ b/llvm/test/tools/llvm-objcopy/ELF/set-symbol-visibility-check-errors.test
@@ -1,21 +1,21 @@
 # RUN: yaml2obj %s -o %t.o
 # RUN: echo 'foo' > %t.symbols
 
-## Check that passing an invalid visibility type generates an error message
+## Check that passing an invalid visibility type generates an error message.
 # RUN: not llvm-objcopy %t.o --set-symbols-visibility=%t.symbols=invalid-type 2>&1 | \
 # RUN:   FileCheck %s --check-prefix=TYPE
 # RUN: not llvm-objcopy %t.o --set-symbol-visibility=foo=invalid-type 2>&1 | \
 # RUN:   FileCheck %s --check-prefix=TYPE
 # TYPE: error: 'invalid-type' is not a valid symbol visibility
 
-## Check that omitting the '=' character generates an error
+## Check that omitting the '=' character generates an error.
 # RUN: not llvm-objcopy %t.o --set-symbols-visibility=%t.symbols,hidden 2>&1 | \
 # RUN:   FileCheck %s --check-prefix=FORMAT -DOPTION=--set-symbols-visibility
 # RUN: not llvm-objcopy %t.o --set-symbol-visibility=foo default 2>&1 | \
 # RUN:   FileCheck %s --check-prefix=FORMAT -DOPTION=--set-symbol-visibility
 # FORMAT: error: bad format for [[OPTION]]
 
-## Check that using an invalid symbol pattern generates an error
+## Check that using an invalid symbol pattern generates an error.
 # RUN: echo '*.' > %t.symbols.regex
 # RUN: not llvm-objcopy %t.o --set-symbols-visibility=%t.symbols.regex=hidden --regex 2>&1 | \
 # RUN:   FileCheck %s --check-prefix=SYMBOL
@@ -23,7 +23,7 @@
 # RUN:   FileCheck %s --check-prefix=SYMBOL
 # SYMBOL: error: cannot compile regular expression '*.': repetition-operator operand invalid
 
-## Check passing an invalid filename generates an error
+## Check passing an invalid filename generates an error.
 # RUN: not llvm-objcopy %t.o --set-symbols-visibility=no_file=hidden 2>&1 | \
 # RUN:   FileCheck %s --check-prefix=FILE -DMSG=%errc_ENOENT
 # FILE: error: 'no_file': [[MSG]]
diff --git a/llvm/test/tools/llvm-objcopy/ELF/set-symbol-visibility-undef-symbol.test b/llvm/test/tools/llvm-objcopy/ELF/set-symbol-visibility-undef-symbol.test
index 158747ca2663f8..b80d37e085f1e5 100644
--- a/llvm/test/tools/llvm-objcopy/ELF/set-symbol-visibility-undef-symbol.test
+++ b/llvm/test/tools/llvm-objcopy/ELF/set-symbol-visibility-undef-symbol.test
@@ -1,4 +1,4 @@
-## Check that symbols with SHN_UNDEF index are ignored when setting visibility
+## Check that symbols with SHN_UNDEF index are ignored when setting visibility.
 # RUN: yaml2obj %s -o %t.o
 # RUN: llvm-objcopy %t.o --set-symbol-visibility=foo=hidden
 # RUN: llvm-readelf -s %t.o | FileCheck %s
diff --git a/llvm/test/tools/llvm-objcopy/ELF/set-symbol-visibility.test b/llvm/test/tools/llvm-objcopy/ELF/set-symbol-visibility.test
index 56c120545a36ea..55a21901a17dfa 100644
--- a/llvm/test/tools/llvm-objcopy/ELF/set-symbol-visibility.test
+++ b/llvm/test/tools/llvm-objcopy/ELF/set-symbol-visibility.test
@@ -1,7 +1,7 @@
 # RUN: yaml2obj --docnum=1 %s -o %t.o
 # RUN: echo '.*' > %t.symbols.regex
 
-## Check that the visibility of all symbols is properly set to DEFAULT
+## Check that the visibility of all symbols is properly set to DEFAULT.
 # RUN: llvm-objcopy %t.o %t0.o --set-symbols-visibility=%t.symbols.regex=default --regex
 # RUN: llvm-readelf -s %t0.o | FileCheck %s --check-prefix=DEF
 
@@ -18,7 +18,7 @@
 # DEF-DAG: DEFAULT     1 protected_global
 # DEF-DAG: DEFAULT     1 protected_weak
 
-## Check that the visibility of all symbols is properly set to HIDDEN
+## Check that the visibility of all symbols is properly set to HIDDEN.
 # RUN: llvm-objcopy %t.o %t1.o --set-symbols-visibility=%t.symbols.regex=hidden --regex
 # RUN: llvm-readelf -s %t1.o | FileCheck %s --check-prefix=HID
 
@@ -35,7 +35,7 @@
 # HID-DAG: HIDDEN      1 protected_global
 # HID-DAG: HIDDEN      1 protected_weak
 
-## Check that the visibility of all symbols is properly set to PROTECTED
+## Check that the visibility of all symbols is properly set to PROTECTED.
 # RUN: llvm-objcopy %t.o %t2.o --set-symbols-visibility=%t.symbols.regex=protected --regex
 # RUN: llvm-readelf -s %t2.o | FileCheck %s --check-prefix=PRO
 
@@ -52,7 +52,7 @@
 # PRO-DAG: PROTECTED   1 protected_global
 # PRO-DAG: PROTECTED   1 protected_weak
 
-## Check that the visibility of all symbols is properly set to INTERNAL
+## Check that the visibility of all symbols is properly set to INTERNAL.
 # RUN: llvm-objcopy %t.o %t3.o --set-symbols-visibility=%t.symbols.regex=internal --regex
 # RUN: llvm-readelf -s %t3.o | FileCheck %s --check-prefix=INT
 
@@ -70,7 +70,7 @@
 # INT-DAG: INTERNAL    1 protected_weak
 
 ## Check that setting the visibility of certain symbols that were read from
-# a file does not affect other symbols
+## a file does not affect other symbols.
 # RUN: echo -e "default_local\ninternal_local" > %t.symbol.list
 # RUN: llvm-objcopy %t.o %t4.o --set-symbols-visibility=%t.symbol.list=hidden
 # RUN: llvm-readelf -s %t4.o | FileCheck %s --check-prefix=FILE
@@ -90,7 +90,7 @@
 # FILE-DAG: PROTECTED   1 protected_weak
 
 ## Check that the visibility of a single symbol is set correctly,
-# and that no other symbols are affected
+## and that no other symbols are affected.
 # RUN: llvm-objcopy %t.o %t5.o --set-symbol-visibility=default_local=hidden \
 # RUN:                         --set-symbol-visibility=internal_local=protected \
 # RUN:                         --set-symbol-visibility=hidden_local=internal \
@@ -112,7 +112,7 @@
 # SINGLE-DAG: PROTECTED   1 protected_weak
 
 ## Check that the visibility of symbols specified by a regex are set correctly,
-# and that no other symbols are affected
+## and that no other symbols are affected.
 # RUN: llvm-objcopy %t.o %t6.o --set-symbol-visibility=.*_local=hidden --regex
 # RUN: llvm-readelf -s %t6.o | FileCheck %s --check-prefix=REGEX
 
@@ -131,7 +131,7 @@
 # REGEX-DAG: PROTECTED   1 protected_weak
 
 ## Check that the visibility of symbols specified by a wildcard are set correctly,
-# and that no other symbols are affected
+## and that no other symbols are affected.
 # RUN: llvm-objcopy %t.o %t7.o --set-symbol-visibility=*_local=hidden --wildcard
 # RUN: llvm-readelf -s %t7.o | FileCheck %s --check-prefix=WILDCARD
 
@@ -150,7 +150,7 @@
 # WILDCARD-DAG: PROTECTED   1 protected_weak
 
 ## Check that the latest option that matches the same symbols as any of the previous
-## options overwrites the visibility of these symbols
+## options overwrites the visibility of these symbols.
 # RUN: echo -e "*_weak\n*_local" > %t.symbols.pattern
 # RUN: llvm-objcopy %t.o %t8.o --set-symbol-visibility=default_*=hidden \
 # RUN:                         --set-symbol-visibility=internal_*=hidden \
@@ -173,7 +173,7 @@
 # REWRITE-DAG: PROTECTED   1 protected_global
 
 ## Check that a symbol name with a special charater is treated as a plain name
-## when pattern matching options are not enabled
+## when pattern matching options are not enabled.
 # RUN: yaml2obj --docnum=2 %s -o %t9.o
 # RUN: llvm-objcopy %t9.o --set-symbol-visibility=f*o=hidden
 # RUN: llvm-readelf -s %t9.o | FileCheck %s --check-prefix=SPECIAL

>From 287cf46269a62fda9e998603c0d2c585934629ba Mon Sep 17 00:00:00 2001
From: Ilia Kuklin <ikuklin at accesssoftek.com>
Date: Tue, 20 Feb 2024 22:20:03 +0500
Subject: [PATCH 24/24] Merge all tests into a single file

---
 .../set-symbol-visibility-check-errors.test   | 36 --------------
 .../set-symbol-visibility-undef-symbol.test   | 15 ------
 .../ELF/set-symbol-visibility.test            | 47 +++++++++++++++++++
 3 files changed, 47 insertions(+), 51 deletions(-)
 delete mode 100644 llvm/test/tools/llvm-objcopy/ELF/set-symbol-visibility-check-errors.test
 delete mode 100644 llvm/test/tools/llvm-objcopy/ELF/set-symbol-visibility-undef-symbol.test

diff --git a/llvm/test/tools/llvm-objcopy/ELF/set-symbol-visibility-check-errors.test b/llvm/test/tools/llvm-objcopy/ELF/set-symbol-visibility-check-errors.test
deleted file mode 100644
index fa63b591ebc079..00000000000000
--- a/llvm/test/tools/llvm-objcopy/ELF/set-symbol-visibility-check-errors.test
+++ /dev/null
@@ -1,36 +0,0 @@
-# RUN: yaml2obj %s -o %t.o
-# RUN: echo 'foo' > %t.symbols
-
-## Check that passing an invalid visibility type generates an error message.
-# RUN: not llvm-objcopy %t.o --set-symbols-visibility=%t.symbols=invalid-type 2>&1 | \
-# RUN:   FileCheck %s --check-prefix=TYPE
-# RUN: not llvm-objcopy %t.o --set-symbol-visibility=foo=invalid-type 2>&1 | \
-# RUN:   FileCheck %s --check-prefix=TYPE
-# TYPE: error: 'invalid-type' is not a valid symbol visibility
-
-## Check that omitting the '=' character generates an error.
-# RUN: not llvm-objcopy %t.o --set-symbols-visibility=%t.symbols,hidden 2>&1 | \
-# RUN:   FileCheck %s --check-prefix=FORMAT -DOPTION=--set-symbols-visibility
-# RUN: not llvm-objcopy %t.o --set-symbol-visibility=foo default 2>&1 | \
-# RUN:   FileCheck %s --check-prefix=FORMAT -DOPTION=--set-symbol-visibility
-# FORMAT: error: bad format for [[OPTION]]
-
-## Check that using an invalid symbol pattern generates an error.
-# RUN: echo '*.' > %t.symbols.regex
-# RUN: not llvm-objcopy %t.o --set-symbols-visibility=%t.symbols.regex=hidden --regex 2>&1 | \
-# RUN:   FileCheck %s --check-prefix=SYMBOL
-# RUN: not llvm-objcopy %t.o --set-symbol-visibility=*.=default --regex 2>&1 | \
-# RUN:   FileCheck %s --check-prefix=SYMBOL
-# SYMBOL: error: cannot compile regular expression '*.': repetition-operator operand invalid
-
-## Check passing an invalid filename generates an error.
-# RUN: not llvm-objcopy %t.o --set-symbols-visibility=no_file=hidden 2>&1 | \
-# RUN:   FileCheck %s --check-prefix=FILE -DMSG=%errc_ENOENT
-# FILE: error: 'no_file': [[MSG]]
-
-!ELF
-FileHeader:
-  Class:   ELFCLASS64
-  Data:    ELFDATA2LSB
-  Type:    ET_REL
-  Machine: EM_X86_64
diff --git a/llvm/test/tools/llvm-objcopy/ELF/set-symbol-visibility-undef-symbol.test b/llvm/test/tools/llvm-objcopy/ELF/set-symbol-visibility-undef-symbol.test
deleted file mode 100644
index b80d37e085f1e5..00000000000000
--- a/llvm/test/tools/llvm-objcopy/ELF/set-symbol-visibility-undef-symbol.test
+++ /dev/null
@@ -1,15 +0,0 @@
-## Check that symbols with SHN_UNDEF index are ignored when setting visibility.
-# RUN: yaml2obj %s -o %t.o
-# RUN: llvm-objcopy %t.o --set-symbol-visibility=foo=hidden
-# RUN: llvm-readelf -s %t.o | FileCheck %s
-# CHECK: DEFAULT   UND foo
-
-!ELF
-FileHeader:
-  Class:   ELFCLASS64
-  Data:    ELFDATA2LSB
-  Type:    ET_REL
-  Machine: EM_X86_64
-Symbols:
-  - Name:     foo
-    Binding:  STB_LOCAL
diff --git a/llvm/test/tools/llvm-objcopy/ELF/set-symbol-visibility.test b/llvm/test/tools/llvm-objcopy/ELF/set-symbol-visibility.test
index 55a21901a17dfa..ce5f5bf62b7a02 100644
--- a/llvm/test/tools/llvm-objcopy/ELF/set-symbol-visibility.test
+++ b/llvm/test/tools/llvm-objcopy/ELF/set-symbol-visibility.test
@@ -182,6 +182,41 @@
 ## Unaffected symbol:
 # SPECIAL-DAG: DEFAULT     1 foo
 
+# RUN: yaml2obj --docnum=3 %s -o %t10.o
+
+## Check that symbols with SHN_UNDEF index are ignored when setting visibility.
+# RUN: llvm-objcopy %t10.o --set-symbol-visibility=foo=hidden
+# RUN: llvm-readelf -s %t10.o | FileCheck %s --check-prefix=UNDEF
+# UNDEF: DEFAULT   UND foo
+
+## Check that passing an invalid visibility type generates an error message.
+# RUN: echo 'foo' > %t.symbols
+# RUN: not llvm-objcopy %t10.o --set-symbols-visibility=%t.symbols=invalid-type 2>&1 | \
+# RUN:   FileCheck %s --check-prefix=TYPE
+# RUN: not llvm-objcopy %t10.o --set-symbol-visibility=foo=invalid-type 2>&1 | \
+# RUN:   FileCheck %s --check-prefix=TYPE
+# TYPE: error: 'invalid-type' is not a valid symbol visibility
+
+## Check that omitting the '=' character generates an error.
+# RUN: not llvm-objcopy %t10.o --set-symbols-visibility=%t.symbols,hidden 2>&1 | \
+# RUN:   FileCheck %s --check-prefix=FORMAT -DOPTION=--set-symbols-visibility
+# RUN: not llvm-objcopy %t10.o --set-symbol-visibility=foo default 2>&1 | \
+# RUN:   FileCheck %s --check-prefix=FORMAT -DOPTION=--set-symbol-visibility
+# FORMAT: error: bad format for [[OPTION]]
+
+## Check that using an invalid symbol pattern generates an error.
+# RUN: echo '*.' > %t.symbols.regex
+# RUN: not llvm-objcopy %t10.o --set-symbols-visibility=%t.symbols.regex=hidden --regex 2>&1 | \
+# RUN:   FileCheck %s --check-prefix=SYMBOL
+# RUN: not llvm-objcopy %t10.o --set-symbol-visibility=*.=default --regex 2>&1 | \
+# RUN:   FileCheck %s --check-prefix=SYMBOL
+# SYMBOL: error: cannot compile regular expression '*.': repetition-operator operand invalid
+
+## Check passing an invalid filename generates an error.
+# RUN: not llvm-objcopy %t10.o --set-symbols-visibility=no_file=hidden 2>&1 | \
+# RUN:   FileCheck %s --check-prefix=NO_FILE -DMSG=%errc_ENOENT
+# NO_FILE: error: 'no_file': [[MSG]]
+
 ---
 !ELF
 FileHeader:
@@ -262,3 +297,15 @@ Symbols:
     Section: .text
     Binding:  STB_LOCAL
 ...
+
+---
+!ELF
+FileHeader:
+  Class:   ELFCLASS64
+  Data:    ELFDATA2LSB
+  Type:    ET_REL
+  Machine: EM_X86_64
+Symbols:
+  - Name:     foo
+    Binding:  STB_LOCAL
+...



More information about the llvm-commits mailing list