+2021-05-04  Fangrui Song  <maskray@google.com>
+
+       PR 27834
+       * options.h (General_options): Make -Bsymbolic and
+       -Bsymbolic-functions special and adjust the help messages. Add
+       enum Bsymbolic_kind and -Bno-symbolic.
+       * options.cc (General_options): Define parse_Bno_symbolic,
+       parse_Bsymbolic_functions, and parse_Bsymbolic.
+
 2021-03-30  Alan Modra  <amodra@gmail.com>
 
        PR gold/27625
 
     printf("   %s\n", *p);
 }
 
+void
+General_options::parse_Bno_symbolic(const char*, const char*,
+                                   Command_line*)
+{
+  this->bsymbolic_ = BSYMBOLIC_NONE;
+}
+
+void
+General_options::parse_Bsymbolic_functions(const char*, const char*,
+                                          Command_line*)
+{
+  this->bsymbolic_ = BSYMBOLIC_FUNCTIONS;
+}
+
+void
+General_options::parse_Bsymbolic(const char*, const char*,
+                                Command_line*)
+{
+  this->bsymbolic_ = BSYMBOLIC_ALL;
+}
+
 void
 General_options::parse_defsym(const char*, const char* arg,
                              Command_line* cmdline)
 
   DEFINE_bool(Bshareable, options::ONE_DASH, '\0', false,
              N_("Generate shared library (alias for -G/-shared)"), NULL);
 
-  DEFINE_bool(Bsymbolic, options::ONE_DASH, '\0', false,
-             N_("Bind defined symbols locally"), NULL);
+  DEFINE_special (Bno_symbolic, options::ONE_DASH, '\0',
+                 N_ ("Don't bind default visibility defined symbols locally "
+                     "for -shared (default)"),
+                 NULL);
 
-  DEFINE_bool(Bsymbolic_functions, options::ONE_DASH, '\0', false,
-             N_("Bind defined function symbols locally"), NULL);
+  DEFINE_special (Bsymbolic_functions, options::ONE_DASH, '\0',
+                 N_ ("Bind default visibility defined function symbols "
+                     "locally for -shared"),
+                 NULL);
+
+  DEFINE_special (
+      Bsymbolic, options::ONE_DASH, '\0',
+      N_ ("Bind default visibility defined symbols locally for -shared"),
+      NULL);
 
   // c
 
   endianness() const
   { return this->endianness_; }
 
+  enum Bsymbolic_kind
+  {
+    BSYMBOLIC_NONE,
+    BSYMBOLIC_FUNCTIONS,
+    BSYMBOLIC_ALL,
+  };
+
+  bool
+  Bsymbolic() const
+  { return this->bsymbolic_ == BSYMBOLIC_ALL; }
+
+  bool
+  Bsymbolic_functions() const
+  { return this->bsymbolic_ == BSYMBOLIC_FUNCTIONS; }
+
   bool
   discard_all() const
   { return this->discard_locals_ == DISCARD_ALL; }
   void
   copy_from_posdep_options(const Position_dependent_options&);
 
+  // Whether we bind default visibility defined symbols locally for -shared.
+  Bsymbolic_kind bsymbolic_;
   // Whether we printed version information.
   bool printed_version_;
   // Whether to mark the stack as executable.