Skip to content

Commit

Permalink
Support -z start-stop-visibility=hidden
Browse files Browse the repository at this point in the history
Fixes #826
  • Loading branch information
rui314 committed Apr 8, 2024
1 parent d432e98 commit 99a5b15
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 10 deletions.
9 changes: 6 additions & 3 deletions elf/cmdline.cc
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,8 @@ inline const char helpmsg[] = R"(
-z nopack-relative-relocs
-z sectionheader Do not omit section header (default)
-z nosectionheader Omit section header
-z start_stop_visibility=[hidden,protected]
Specify symbol visibility for "__start_SECNAME" and "__stop_SECNAME" symbols
-z separate-loadable-segments
Separate all loadable segments onto different pages
-z separate-code Separate code and data onto different pages
Expand Down Expand Up @@ -937,9 +939,10 @@ std::vector<std::string> parse_nonpositional_args(Context<E> &ctx) {
ctx.page_size = parse_number(ctx, "-z max-page-size", arg);
if (!has_single_bit(ctx.page_size))
Fatal(ctx) << "-z max-page-size " << arg << ": value must be a power of 2";
} else if (read_z_arg("start-stop-visibility")) {
if (arg != "hidden")
Fatal(ctx) << "-z start-stop-visibility: unsupported visibility: " << arg;
} else if (read_z_flag("start-stop-visibility=protected")) {
ctx.arg.z_start_stop_visibility_protected = true;
} else if (read_z_flag("start-stop-visibility=hidden")) {
ctx.arg.z_start_stop_visibility_protected = false;
} else if (read_z_flag("noexecstack")) {
ctx.arg.z_execstack = false;
} else if (read_z_flag("relro")) {
Expand Down
1 change: 1 addition & 0 deletions elf/mold.h
Original file line number Diff line number Diff line change
Expand Up @@ -1725,6 +1725,7 @@ struct Context {
bool z_rewrite_endbr = false;
bool z_sectionheader = true;
bool z_shstk = false;
bool z_start_stop_visibility_protected = false;
bool z_text = false;
i64 filler = -1;
i64 spare_dynamic_tags = 5;
Expand Down
14 changes: 10 additions & 4 deletions elf/passes.cc
Original file line number Diff line number Diff line change
Expand Up @@ -830,14 +830,20 @@ void add_synthetic_symbols(Context<E> &ctx) {
if constexpr (is_ppc32<E>)
ctx.extra._SDA_BASE_ = add("_SDA_BASE_");

auto add_start_stop = [&](std::string s) {
add(save_string(ctx, s));
if (ctx.arg.z_start_stop_visibility_protected)
get_symbol(ctx, save_string(ctx, s))->is_exported = true;
};

for (Chunk<E> *chunk : ctx.chunks) {
if (std::optional<std::string> name = get_start_stop_name(ctx, *chunk)) {
add(save_string(ctx, "__start_" + *name));
add(save_string(ctx, "__stop_" + *name));
add_start_stop("__start_" + *name);
add_start_stop("__stop_" + *name);

if (ctx.arg.physical_image_base) {
add(save_string(ctx, "__phys_start_" + *name));
add(save_string(ctx, "__phys_stop_" + *name));
add_start_stop("__phys_start_" + *name);
add_start_stop("__phys_stop_" + *name);
}
}
}
Expand Down
28 changes: 25 additions & 3 deletions test/elf/z-start-stop-visibility.sh
Original file line number Diff line number Diff line change
@@ -1,6 +1,28 @@
#!/bin/bash
. $(dirname $0)/common.inc

./mold -z start-stop-visibility=hidden --version > /dev/null
! ./mold -z start-stop-visibility=protected --version 2> $t/log
grep -q 'unsupported visibility: protected' $t/log
cat <<EOF | $CC -o $t/a.o -c -xc -
#include <stdio.h>
__attribute__((section("hello")))
static char msg[] = "Hello world";
int main() {
printf("%s\n", msg);
}
EOF

$CC -B. -o $t/exe1 $t/a.o
readelf -W --dyn-syms $t/exe1 > $t/log1
! grep -q __start_hello $t/log1 || false
! grep -q __stop_hello $t/log1 || false

$CC -B. -o $t/exe2 $t/a.o -Wl,-z,start-stop-visibility=hidden
readelf -W --dyn-syms $t/exe2 > $t/log2
! grep -q __start_hello $t/log2 || false
! grep -q __stop_hello $t/log2 || false

$CC -B. -o $t/exe3 $t/a.o -Wl,-z,start-stop-visibility=protected
readelf -W --dyn-syms $t/exe3 > $t/log3
grep -q __start_hello $t/log3
grep -q __stop_hello $t/log3

0 comments on commit 99a5b15

Please sign in to comment.