gold, ld: Implement -z start-stop-visibility=... option.

gold/
	Implement -z start-stop-visibility=... option.
	* options.h (class General_options): Handle -z start-stop-visibility=.
	(General_options::start_stop_visibility_enum): New public method.
	(General_options::set_start_stop_visibility_enum): New private method.
	(General_options::start_stop_visibility_enum_): New private member.
	* options.cc (General_options::General_options): Add initializer.
	(General_options::finalize): Set this->start_stop_visibility_enum_
	from string value.
	* layout.cc (Layout::define_section_symbols): Use option setting.

bfd/
	* elflink.c (bfd_elf_define_start_stop): Use start_stop_visibility
	field of bfd_link_info.

include/
	* bfdlink.h (struct bfd_link_info): New field start_stop_visibility.

ld/
	* NEWS: Mention -z start-stop-visibility=... option for ELF.
	* ld.texi (Options): Document -z start-stop-visibility=... option.
	* ldmain.c (main): Initialize link_info.start_stop_visibility.
	* emultempl/elf.em (gld${EMULATION_NAME}_handle_option):
	Parse -z start-stop-visibility=... option.
This commit is contained in:
Roland McGrath 2020-06-15 11:45:02 -07:00
parent 6692031743
commit cae64165f4
13 changed files with 103 additions and 7 deletions

View File

@ -1,3 +1,8 @@
2020-06-15 Roland McGrath <mcgrathr@google.com>
* elflink.c (bfd_elf_define_start_stop): Use start_stop_visibility
field of bfd_link_info.
2020-06-15 Alan Modra <amodra@gmail.com> 2020-06-15 Alan Modra <amodra@gmail.com>
* config.bfd: Obsolete powerpcle-*-pe targets. * config.bfd: Obsolete powerpcle-*-pe targets.
@ -346,7 +351,7 @@
(aout_link_add_symbols): e517df3dbf7 PR 19629 - Check for out of (aout_link_add_symbols): e517df3dbf7 PR 19629 - Check for out of
range string table offsets. range string table offsets.
531336e3a0b PR 20909 - Fix off-by-one error in check for an 531336e3a0b PR 20909 - Fix off-by-one error in check for an
illegal string offset. illegal string offset.
(aout_link_includes_newfunc): Add comment. (aout_link_includes_newfunc): Add comment.
(pdp11_aout_link_input_section): ad756e3f9e6 - Return with an error (pdp11_aout_link_input_section): ad756e3f9e6 - Return with an error
on unexpected relocation type rather than ASSERT. on unexpected relocation type rather than ASSERT.

View File

@ -14837,7 +14837,8 @@ bfd_elf_define_start_stop (struct bfd_link_info *info,
else else
{ {
if (ELF_ST_VISIBILITY (h->other) == STV_DEFAULT) if (ELF_ST_VISIBILITY (h->other) == STV_DEFAULT)
h->other = (h->other & ~ELF_ST_VISIBILITY (-1)) | STV_PROTECTED; h->other = ((h->other & ~ELF_ST_VISIBILITY (-1))
| info->start_stop_visibility);
if (was_dynamic) if (was_dynamic)
bfd_elf_link_record_dynamic_symbol (info, h); bfd_elf_link_record_dynamic_symbol (info, h);
} }

View File

@ -1,3 +1,15 @@
2020-06-15 Roland McGrath <mcgrathr@google.com>
Implement -z start-stop-visibility=... option.
* options.h (class General_options): Handle -z start-stop-visibility=.
(General_options::start_stop_visibility_enum): New public method.
(General_options::set_start_stop_visibility_enum): New private method.
(General_options::start_stop_visibility_enum_): New private member.
* options.cc (General_options::General_options): Add initializer.
(General_options::finalize): Set this->start_stop_visibility_enum_
from string value.
* layout.cc (Layout::define_section_symbols): Use option setting.
2020-06-06 Alan Modra <amodra@gmail.com> 2020-06-06 Alan Modra <amodra@gmail.com>
* powerpc.cc: Update throughout for reloc renaming. * powerpc.cc: Update throughout for reloc renaming.

View File

@ -2474,6 +2474,7 @@ Layout::create_initial_dynamic_sections(Symbol_table* symtab)
void void
Layout::define_section_symbols(Symbol_table* symtab) Layout::define_section_symbols(Symbol_table* symtab)
{ {
const elfcpp::STV visibility = parameters->options().start_stop_visibility_enum();
for (Section_list::const_iterator p = this->section_list_.begin(); for (Section_list::const_iterator p = this->section_list_.begin();
p != this->section_list_.end(); p != this->section_list_.end();
++p) ++p)
@ -2495,7 +2496,7 @@ Layout::define_section_symbols(Symbol_table* symtab)
0, // symsize 0, // symsize
elfcpp::STT_NOTYPE, elfcpp::STT_NOTYPE,
elfcpp::STB_GLOBAL, elfcpp::STB_GLOBAL,
elfcpp::STV_PROTECTED, visibility,
0, // nonvis 0, // nonvis
false, // offset_is_from_end false, // offset_is_from_end
true); // only_if_ref true); // only_if_ref
@ -2508,7 +2509,7 @@ Layout::define_section_symbols(Symbol_table* symtab)
0, // symsize 0, // symsize
elfcpp::STT_NOTYPE, elfcpp::STT_NOTYPE,
elfcpp::STB_GLOBAL, elfcpp::STB_GLOBAL,
elfcpp::STV_PROTECTED, visibility,
0, // nonvis 0, // nonvis
true, // offset_is_from_end true, // offset_is_from_end
true); // only_if_ref true); // only_if_ref

View File

@ -997,7 +997,8 @@ General_options::General_options()
fix_v4bx_(FIX_V4BX_NONE), fix_v4bx_(FIX_V4BX_NONE),
endianness_(ENDIANNESS_NOT_SET), endianness_(ENDIANNESS_NOT_SET),
discard_locals_(DISCARD_SEC_MERGE), discard_locals_(DISCARD_SEC_MERGE),
orphan_handling_enum_(ORPHAN_PLACE) orphan_handling_enum_(ORPHAN_PLACE),
start_stop_visibility_enum_(elfcpp::STV_PROTECTED)
{ {
// Turn off option registration once construction is complete. // Turn off option registration once construction is complete.
gold::options::ready_to_register = false; gold::options::ready_to_register = false;
@ -1169,6 +1170,19 @@ General_options::finalize()
this->set_orphan_handling_enum(ORPHAN_ERROR); this->set_orphan_handling_enum(ORPHAN_ERROR);
} }
// Parse the -z start-stop-visibility argument.
if (this->user_set_start_stop_visibility())
{
if (strcmp(this->start_stop_visibility(), "default") == 0)
this->set_start_stop_visibility_enum(elfcpp::STV_DEFAULT);
else if (strcmp(this->start_stop_visibility(), "internal") == 0)
this->set_start_stop_visibility_enum(elfcpp::STV_INTERNAL);
else if (strcmp(this->start_stop_visibility(), "hidden") == 0)
this->set_start_stop_visibility_enum(elfcpp::STV_HIDDEN);
else if (strcmp(this->start_stop_visibility(), "protected") == 0)
this->set_start_stop_visibility_enum(elfcpp::STV_PROTECTED);
}
// -M is equivalent to "-Map -". // -M is equivalent to "-Map -".
if (this->print_map() && !this->user_set_Map()) if (this->print_map() && !this->user_set_Map())
{ {

View File

@ -1500,6 +1500,11 @@ class General_options
N_("Don't mark variables read-only after relocation")); N_("Don't mark variables read-only after relocation"));
DEFINE_uint64(stack_size, options::DASH_Z, '\0', 0, DEFINE_uint64(stack_size, options::DASH_Z, '\0', 0,
N_("Set PT_GNU_STACK segment p_memsz to SIZE"), N_("SIZE")); N_("Set PT_GNU_STACK segment p_memsz to SIZE"), N_("SIZE"));
DEFINE_enum(start_stop_visibility, options::DASH_Z, '\0', "protected",
N_("ELF symbol visibility for synthesized "
"__start_* and __stop_* symbols"),
("[default,internal,hidden,protected]"),
{"default", "internal", "hidden", "protected"});
DEFINE_bool(text, options::DASH_Z, '\0', false, DEFINE_bool(text, options::DASH_Z, '\0', false,
N_("Do not permit relocations in read-only segments"), N_("Do not permit relocations in read-only segments"),
N_("Permit relocations in read-only segments")); N_("Permit relocations in read-only segments"));
@ -1750,6 +1755,10 @@ class General_options
orphan_handling_enum() const orphan_handling_enum() const
{ return this->orphan_handling_enum_; } { return this->orphan_handling_enum_; }
elfcpp::STV
start_stop_visibility_enum() const
{ return this->start_stop_visibility_enum_; }
private: private:
// Don't copy this structure. // Don't copy this structure.
General_options(const General_options&); General_options(const General_options&);
@ -1809,6 +1818,10 @@ class General_options
set_orphan_handling_enum(Orphan_handling value) set_orphan_handling_enum(Orphan_handling value)
{ this->orphan_handling_enum_ = value; } { this->orphan_handling_enum_ = value; }
void
set_start_stop_visibility_enum(elfcpp::STV value)
{ this->start_stop_visibility_enum_ = value; }
// These are called by finalize() to set up the search-path correctly. // These are called by finalize() to set up the search-path correctly.
void void
add_to_library_path_with_sysroot(const std::string& arg) add_to_library_path_with_sysroot(const std::string& arg)
@ -1876,6 +1889,8 @@ class General_options
std::vector<Position_dependent_options*> options_stack_; std::vector<Position_dependent_options*> options_stack_;
// Orphan handling option, decoded to an enum value. // Orphan handling option, decoded to an enum value.
Orphan_handling orphan_handling_enum_; Orphan_handling orphan_handling_enum_;
// Symbol visibility for __start_* / __stop_* magic symbols.
elfcpp::STV start_stop_visibility_enum_;
}; };
// The position-dependent options. We use this to store the state of // The position-dependent options. We use this to store the state of

View File

@ -1,3 +1,7 @@
2020-06-12 Roland McGrath <mcgrathr@google.com>
* bfdlink.h (struct bfd_link_info): New field start_stop_visibility.
2020-06-12 Nelson Chu <nelson.chu@sifive.com> 2020-06-12 Nelson Chu <nelson.chu@sifive.com>
* opcode/riscv-opc.h: Update the defined versions of CSR from * opcode/riscv-opc.h: Update the defined versions of CSR from

View File

@ -542,10 +542,10 @@ struct bfd_link_info
Normally these optimizations are disabled by default but some targets Normally these optimizations are disabled by default but some targets
prefer to enable them by default. So this field is a tri-state variable. prefer to enable them by default. So this field is a tri-state variable.
The values are: The values are:
zero: Enable the optimizations (either from --relax being specified on zero: Enable the optimizations (either from --relax being specified on
the command line or the backend's before_allocation emulation function. the command line or the backend's before_allocation emulation function.
positive: The user has requested that these optimizations be disabled. positive: The user has requested that these optimizations be disabled.
(Via the --no-relax command line option). (Via the --no-relax command line option).
@ -649,6 +649,9 @@ struct bfd_link_info
/* May be used to set DT_FLAGS_1 for ELF. */ /* May be used to set DT_FLAGS_1 for ELF. */
bfd_vma flags_1; bfd_vma flags_1;
/* May be used to set ELF visibility for __start_* / __stop_. */
unsigned int start_stop_visibility;
/* Start and end of RELRO region. */ /* Start and end of RELRO region. */
bfd_vma relro_start, relro_end; bfd_vma relro_start, relro_end;

View File

@ -1,3 +1,11 @@
2020-06-15 Roland McGrath <mcgrathr@google.com>
* NEWS: Mention -z start-stop-visibility=... option for ELF.
* ld.texi (Options): Document -z start-stop-visibility=... option.
* ldmain.c (main): Initialize link_info.start_stop_visibility.
* emultempl/elf.em (gld${EMULATION_NAME}_handle_option):
Parse -z start-stop-visibility=... option.
2020-06-15 Alan Modra <amodra@gmail.com> 2020-06-15 Alan Modra <amodra@gmail.com>
* testsuite/ld-scripts/include.exp: Don't load ld-lib.exp. * testsuite/ld-scripts/include.exp: Don't load ld-lib.exp.

View File

@ -25,6 +25,9 @@
searched relative to the directory of the linker script before other search searched relative to the directory of the linker script before other search
paths. paths.
* Add ELF linker command-line option `-z start-stop-visibility=...' to control
the visibility of synthetic `__start_SECNAME` and `__stop_SECNAME` symbols.
Changes in 2.34: Changes in 2.34:
* The ld check for "PHDR segment not covered by LOAD segment" is more * The ld check for "PHDR segment not covered by LOAD segment" is more

View File

@ -749,6 +749,21 @@ fragment <<EOF
{ {
link_info.flags_1 |= DF_1_GLOBAUDIT; link_info.flags_1 |= DF_1_GLOBAUDIT;
} }
else if (CONST_STRNEQ (optarg, "start-stop-visibility="))
{
if (strcmp (optarg, "start-stop-visibility=default") == 0)
link_info.start_stop_visibility = STV_DEFAULT;
else if (strcmp (optarg, "start-stop-visibility=internal") == 0)
link_info.start_stop_visibility = STV_INTERNAL;
else if (strcmp (optarg, "start-stop-visibility=hidden") == 0)
link_info.start_stop_visibility = STV_HIDDEN;
else if (strcmp (optarg, "start-stop-visibility=protected") == 0)
link_info.start_stop_visibility = STV_PROTECTED;
else
einfo (_("%F%P: invalid visibility in \`-z %s'; "
"must be default, internal, hidden, or protected"),
optarg);
}
EOF EOF
if test x"$GENERATE_SHLIB_SCRIPT" = xyes; then if test x"$GENERATE_SHLIB_SCRIPT" = xyes; then

View File

@ -1373,6 +1373,19 @@ Specify a stack size for an ELF @code{PT_GNU_STACK} segment.
Specifying zero will override any default non-zero sized Specifying zero will override any default non-zero sized
@code{PT_GNU_STACK} segment creation. @code{PT_GNU_STACK} segment creation.
@item start-stop-visibility=@var{value}
@cindex visibility
@cindex ELF symbol visibility
Specify the ELF symbol visibility for synthesized
@code{__start_SECNAME} and @code{__stop_SECNAME} symbols (@pxref{Input
Section Example}). @var{value} must be exactly @samp{default},
@samp{internal}, @samp{hidden}, or @samp{protected}. If no @samp{-z
start-stop-visibility} option is given, @samp{protected} is used for
compatibility with historical practice. However, it's highly
recommended to use @samp{-z start-stop-visibility=hidden} in new
programs and shared libraries so that these symbols are not exported
between shared objects, which is not usually what's intended.
@item text @item text
@itemx notext @itemx notext
@itemx textoff @itemx textoff

View File

@ -27,6 +27,7 @@
#include "bfdlink.h" #include "bfdlink.h"
#include "ctf-api.h" #include "ctf-api.h"
#include "filenames.h" #include "filenames.h"
#include "elf/common.h"
#include "ld.h" #include "ld.h"
#include "ldmain.h" #include "ldmain.h"
@ -307,6 +308,7 @@ main (int argc, char **argv)
#ifdef DEFAULT_NEW_DTAGS #ifdef DEFAULT_NEW_DTAGS
link_info.new_dtags = DEFAULT_NEW_DTAGS; link_info.new_dtags = DEFAULT_NEW_DTAGS;
#endif #endif
link_info.start_stop_visibility = STV_PROTECTED;
ldfile_add_arch (""); ldfile_add_arch ("");
emulation = get_emulation (argc, argv); emulation = get_emulation (argc, argv);