summaryrefslogtreecommitdiff
path: root/sys-devel/mold/files
diff options
context:
space:
mode:
authorV3n3RiX <venerix@koprulu.sector>2023-12-28 07:37:55 +0000
committerV3n3RiX <venerix@koprulu.sector>2023-12-28 07:37:55 +0000
commitd46d1d3a5897cade51811b3848c7bf27969da625 (patch)
tree0dabb04db53e3fe66abe43df0a3cdff5d3b664db /sys-devel/mold/files
parente67d5b4ba05349b3bf4229d0cf7d069809c4420e (diff)
gentoo auto-resync : 28:12:2023 - 07:37:55
Diffstat (limited to 'sys-devel/mold/files')
-rw-r--r--sys-devel/mold/files/mold-2.3.2-mimalloc-visibility-interposition.patch495
1 files changed, 0 insertions, 495 deletions
diff --git a/sys-devel/mold/files/mold-2.3.2-mimalloc-visibility-interposition.patch b/sys-devel/mold/files/mold-2.3.2-mimalloc-visibility-interposition.patch
deleted file mode 100644
index e569bfaf3013..000000000000
--- a/sys-devel/mold/files/mold-2.3.2-mimalloc-visibility-interposition.patch
+++ /dev/null
@@ -1,495 +0,0 @@
-https://bugs.gentoo.org/917089
-https://github.com/microsoft/mimalloc/issues/360
-https://github.com/rui314/mold/issues/1071
-https://github.com/rui314/mold/commit/da3f5dd4ecf4faaba466ba41c7c30ba4f8f73bfd
-
-From da3f5dd4ecf4faaba466ba41c7c30ba4f8f73bfd Mon Sep 17 00:00:00 2001
-From: Rui Ueyama <ruiu@cs.stanford.edu>
-Date: Sat, 11 Nov 2023 17:59:54 +0900
-Subject: [PATCH] Fix --dynamic-list for DSOs
-
---dynamic-list, --export-dynamic-symbol and --export-dynamic-symbol-list
-have different semantics for executables and DSOs. If the output is an
-executable, they specify a list of symbols that are to be exported.
-If the output is a shared object, they specify the list of symbols that
-are to be interposable.
-
-mold havne't implemented the latter semantics. This commit fixes that
-issue.
-
-Fixes https://github.com/rui314/mold/issues/1071
----
- elf/cmdline.cc | 25 +++-----
- elf/linker-script.cc | 35 ++++++-----
- elf/main.cc | 16 -----
- elf/mold.h | 17 +++--
- elf/output-chunks.cc | 8 ++-
- elf/passes.cc | 122 +++++++++++++++++++++++++++++-------
- test/elf/dynamic-list4.sh | 44 +++++++++++++
- test/elf/version-script6.sh | 4 +-
- 8 files changed, 194 insertions(+), 77 deletions(-)
- create mode 100755 test/elf/dynamic-list4.sh
-
-diff --git a/elf/cmdline.cc b/elf/cmdline.cc
-index 6bc13a300..6c06b4b14 100644
---- a/elf/cmdline.cc
-+++ b/elf/cmdline.cc
-@@ -1104,21 +1104,21 @@ std::vector<std::string> parse_nonpositional_args(Context<E> &ctx) {
- } else if (read_flag("no-keep-memory")) {
- } else if (read_arg("max-cache-size")) {
- } else if (read_arg("version-script")) {
-- // --version-script, --dynamic-list and --export-dynamic-symbol[-list]
-- // are treated as positional arguments even though they are actually not
-- // positional. This is because linker scripts (a positional argument)
-- // can also specify a version script, and it's better to consolidate
-- // parsing in read_input_files. In particular, version scripts can
-- // modify ctx.default_version which we initialize *after* parsing
-- // non-positional args, so the parsing cannot be done right here.
-+ // --version-script is treated as positional arguments even though
-+ // they are actually not positional. This is because linker scripts
-+ // (a positional argument) can also specify a version script, and
-+ // it's better to consolidate parsing in read_input_files. In
-+ // particular, version scripts can modify ctx.default_version which
-+ // we initialize *after* parsing non-positional args, so the parsing
-+ // cannot be done right here.
- remaining.push_back("--version-script=" + std::string(arg));
- } else if (read_arg("dynamic-list")) {
- ctx.arg.Bsymbolic = true;
-- remaining.push_back("--dynamic-list=" + std::string(arg));
-+ append(ctx.dynamic_list_patterns, parse_dynamic_list(ctx, arg));
- } else if (read_arg("export-dynamic-symbol")) {
-- remaining.push_back("--export-dynamic-symbol=" + std::string(arg));
-+ ctx.dynamic_list_patterns.push_back({arg, "<command line>"});
- } else if (read_arg("export-dynamic-symbol-list")) {
-- remaining.push_back("--export-dynamic-symbol-list=" + std::string(arg));
-+ append(ctx.dynamic_list_patterns, parse_dynamic_list(ctx, arg));
- } else if (read_flag("as-needed")) {
- remaining.push_back("--as-needed");
- } else if (read_flag("no-as-needed")) {
-@@ -1228,11 +1228,6 @@ std::vector<std::string> parse_nonpositional_args(Context<E> &ctx) {
- if (char *env = getenv("MOLD_REPRO"); env && env[0])
- ctx.arg.repro = true;
-
-- if (ctx.arg.shared || ctx.arg.export_dynamic)
-- ctx.default_version = VER_NDX_GLOBAL;
-- else
-- ctx.default_version = VER_NDX_LOCAL;
--
- if (ctx.arg.default_symver) {
- std::string ver = ctx.arg.soname.empty() ?
- filepath(ctx.arg.output).filename().string() : std::string(ctx.arg.soname);
-diff --git a/elf/linker-script.cc b/elf/linker-script.cc
-index 4bdc19e7c..7ad500bb8 100644
---- a/elf/linker-script.cc
-+++ b/elf/linker-script.cc
-@@ -312,7 +312,6 @@ read_version_script_commands(Context<E> &ctx, std::span<std::string_view> &tok,
-
- if (tok[0] == "*") {
- ctx.default_version = (is_global ? ver_idx : (u32)VER_NDX_LOCAL);
-- ctx.default_version_from_version_script = true;
- } else if (is_global) {
- ctx.version_patterns.push_back({unquote(tok[0]), current_file<E>->name,
- ver_str, ver_idx, is_cpp});
-@@ -367,7 +366,9 @@ void parse_version_script(Context<E> &ctx, MappedFile<Context<E>> *mf) {
- }
-
- template <typename E>
--void read_dynamic_list_commands(Context<E> &ctx, std::span<std::string_view> &tok,
-+void read_dynamic_list_commands(Context<E> &ctx,
-+ std::vector<DynamicPattern> &result,
-+ std::span<std::string_view> &tok,
- bool is_cpp) {
- while (!tok.empty() && tok[0] != "}") {
- if (tok[0] == "extern") {
-@@ -376,11 +377,11 @@ void read_dynamic_list_commands(Context<E> &ctx, std::span<std::string_view> &to
- if (!tok.empty() && tok[0] == "\"C\"") {
- tok = tok.subspan(1);
- tok = skip(ctx, tok, "{");
-- read_dynamic_list_commands(ctx, tok, false);
-+ read_dynamic_list_commands(ctx, result, tok, false);
- } else {
- tok = skip(ctx, tok, "\"C++\"");
- tok = skip(ctx, tok, "{");
-- read_dynamic_list_commands(ctx, tok, true);
-+ read_dynamic_list_commands(ctx, result, tok, true);
- }
-
- tok = skip(ctx, tok, "}");
-@@ -388,29 +389,32 @@ void read_dynamic_list_commands(Context<E> &ctx, std::span<std::string_view> &to
- continue;
- }
-
-- if (tok[0] == "*")
-- ctx.default_version = VER_NDX_GLOBAL;
-- else
-- ctx.version_patterns.push_back({unquote(tok[0]), current_file<E>->name,
-- "global", VER_NDX_GLOBAL, is_cpp});
--
-+ result.push_back({unquote(tok[0]), "", is_cpp});
- tok = skip(ctx, tok.subspan(1), ";");
- }
- }
-
- template <typename E>
--void parse_dynamic_list(Context<E> &ctx, MappedFile<Context<E>> *mf) {
-- current_file<E> = mf;
-- std::vector<std::string_view> vec = tokenize(ctx, mf->get_contents());
-+std::vector<DynamicPattern>
-+parse_dynamic_list(Context<E> &ctx, std::string_view path) {
-+ std::string_view contents =
-+ MappedFile<Context<E>>::must_open(ctx, std::string(path))->get_contents();
-+ std::vector<std::string_view> vec = tokenize(ctx, contents);
- std::span<std::string_view> tok = vec;
-+ std::vector<DynamicPattern> result;
-
- tok = skip(ctx, tok, "{");
-- read_dynamic_list_commands(ctx, tok, false);
-+ read_dynamic_list_commands(ctx, result, tok, false);
- tok = skip(ctx, tok, "}");
- tok = skip(ctx, tok, ";");
-
- if (!tok.empty())
- SyntaxError(ctx, tok[0]) << "trailing garbage token";
-+
-+ for (DynamicPattern &p : result)
-+ p.source = path;
-+
-+ return result;
- }
-
- using E = MOLD_TARGET;
-@@ -418,6 +422,7 @@ using E = MOLD_TARGET;
- template void parse_linker_script(Context<E> &, MappedFile<Context<E>> *);
- template std::string_view get_script_output_type(Context<E> &, MappedFile<Context<E>> *);
- template void parse_version_script(Context<E> &, MappedFile<Context<E>> *);
--template void parse_dynamic_list(Context<E> &, MappedFile<Context<E>> *);
-+template std::vector<DynamicPattern> parse_dynamic_list(Context<E> &, std::string_view);
-+
-
- } // namespace mold::elf
-diff --git a/elf/main.cc b/elf/main.cc
-index c4f3cd6ff..6df00cfe9 100644
---- a/elf/main.cc
-+++ b/elf/main.cc
-@@ -299,22 +299,6 @@ static void read_input_files(Context<E> &ctx, std::span<std::string> args) {
- if (!mf)
- Fatal(ctx) << "--version-script: file not found: " << arg;
- parse_version_script(ctx, mf);
-- } else if (remove_prefix(arg, "--dynamic-list=")) {
-- MappedFile<Context<E>> *mf = find_from_search_paths(ctx, std::string(arg));
-- if (!mf)
-- Fatal(ctx) << "--dynamic-list: file not found: " << arg;
-- parse_dynamic_list(ctx, mf);
-- } else if (remove_prefix(arg, "--export-dynamic-symbol=")) {
-- if (arg == "*")
-- ctx.default_version = VER_NDX_GLOBAL;
-- else
-- ctx.version_patterns.push_back({arg, "--export-dynamic-symbol",
-- "global", VER_NDX_GLOBAL, false});
-- } else if (remove_prefix(arg, "--export-dynamic-symbol-list=")) {
-- MappedFile<Context<E>> *mf = find_from_search_paths(ctx, std::string(arg));
-- if (!mf)
-- Fatal(ctx) << "--export-dynamic-symbol-list: file not found: " << arg;
-- parse_dynamic_list(ctx, mf);
- } else if (arg == "--push-state") {
- state.push_back({ctx.as_needed, ctx.whole_archive, ctx.is_static,
- ctx.in_lib});
-diff --git a/elf/mold.h b/elf/mold.h
-index 7ff7c2e6f..d593f6840 100644
---- a/elf/mold.h
-+++ b/elf/mold.h
-@@ -1281,8 +1281,15 @@ get_script_output_type(Context<E> &ctx, MappedFile<Context<E>> *mf);
- template <typename E>
- void parse_version_script(Context<E> &ctx, MappedFile<Context<E>> *mf);
-
-+struct DynamicPattern {
-+ std::string_view pattern;
-+ std::string_view source;
-+ bool is_cpp = false;
-+};
-+
- template <typename E>
--void parse_dynamic_list(Context<E> &ctx, MappedFile<Context<E>> *mf);
-+std::vector<DynamicPattern>
-+parse_dynamic_list(Context<E> &ctx, std::string_view path);
-
- //
- // lto.cc
-@@ -1733,13 +1740,11 @@ struct Context {
- } arg;
-
- std::vector<VersionPattern> version_patterns;
-- u16 default_version = VER_NDX_GLOBAL;
-+ std::vector<DynamicPattern> dynamic_list_patterns;
-+ i64 default_version = -1;
- i64 page_size = E::page_size;
- std::optional<int> global_lock_fd;
-
-- // true if default_version is set by a wildcard in version script.
-- bool default_version_from_version_script = false;
--
- // Reader context
- bool as_needed = false;
- bool whole_archive = false;
-@@ -2034,7 +2039,7 @@ class Symbol {
- i32 sym_idx = -1;
-
- i32 aux_idx = -1;
-- u16 ver_idx = 0;
-+ i32 ver_idx = -1;
-
- // `flags` has NEEDS_ flags.
- Atomic<u8> flags = 0;
-diff --git a/elf/output-chunks.cc b/elf/output-chunks.cc
-index f44d448ac..00d5538df 100644
---- a/elf/output-chunks.cc
-+++ b/elf/output-chunks.cc
-@@ -2550,8 +2550,12 @@ void VerdefSection<E>::construct(Context<E> &ctx) {
- for (std::string_view verstr : ctx.arg.version_definitions)
- write(verstr, idx++, 0);
-
-- for (Symbol<E> *sym : std::span<Symbol<E> *>(ctx.dynsym->symbols).subspan(1))
-- ctx.versym->contents[sym->get_dynsym_idx(ctx)] = sym->ver_idx;
-+ for (Symbol<E> *sym : std::span<Symbol<E> *>(ctx.dynsym->symbols).subspan(1)) {
-+ i64 ver = sym->ver_idx;
-+ if (ver == -1)
-+ ver = VER_NDX_GLOBAL;
-+ ctx.versym->contents[sym->get_dynsym_idx(ctx)] = ver;
-+ }
- }
-
- template <typename E>
-diff --git a/elf/passes.cc b/elf/passes.cc
-index c6ee0f66b..8c7d5d0f5 100644
---- a/elf/passes.cc
-+++ b/elf/passes.cc
-@@ -1612,9 +1612,6 @@ template <typename E>
- void apply_version_script(Context<E> &ctx) {
- Timer t(ctx, "apply_version_script");
-
-- // If all patterns are simple (i.e. not containing any meta-
-- // characters and is not a C++ name), we can simply look up
-- // symbols.
- auto is_simple = [&] {
- for (VersionPattern &v : ctx.version_patterns)
- if (v.is_cpp || v.pattern.find_first_of("*?[") != v.pattern.npos)
-@@ -1622,6 +1619,9 @@ void apply_version_script(Context<E> &ctx) {
- return true;
- };
-
-+ // If all patterns are simple (i.e. not containing any meta-
-+ // characters and is not a C++ name), we can simply look up
-+ // symbols.
- if (is_simple()) {
- for (VersionPattern &v : ctx.version_patterns) {
- Symbol<E> *sym = get_symbol(ctx, v.pattern);
-@@ -1747,44 +1747,124 @@ void compute_import_export(Context<E> &ctx) {
- if (!ctx.arg.shared) {
- tbb::parallel_for_each(ctx.dsos, [&](SharedFile<E> *file) {
- for (Symbol<E> *sym : file->symbols) {
-- if (sym->file && !sym->file->is_dso && sym->visibility != STV_HIDDEN) {
-- if (sym->ver_idx != VER_NDX_LOCAL ||
-- !ctx.default_version_from_version_script) {
-- std::scoped_lock lock(sym->mu);
-- sym->is_exported = true;
-- }
-+ if (sym->file && !sym->file->is_dso && sym->visibility != STV_HIDDEN &&
-+ sym->ver_idx != VER_NDX_LOCAL) {
-+ std::scoped_lock lock(sym->mu);
-+ sym->is_exported = true;
- }
- }
- });
- }
-
-+ auto should_export = [&](Symbol<E> &sym) {
-+ if (sym.visibility == STV_HIDDEN)
-+ return false;
-+
-+ switch (sym.ver_idx) {
-+ case -1:
-+ if (ctx.arg.shared)
-+ return !((ObjectFile<E> *)sym.file)->exclude_libs;
-+ return ctx.arg.export_dynamic;
-+ case VER_NDX_LOCAL:
-+ return false;
-+ default:
-+ return true;
-+ }
-+ };
-+
- // Export symbols that are not hidden or marked as local.
- // We also want to mark imported symbols as such.
- tbb::parallel_for_each(ctx.objs, [&](ObjectFile<E> *file) {
- for (Symbol<E> *sym : file->get_global_syms()) {
-- if (!sym->file || sym->visibility == STV_HIDDEN ||
-- sym->ver_idx == VER_NDX_LOCAL)
-- continue;
--
-- // If we are using a symbol in a DSO, we need to import it at runtime.
-- if (sym->file != file && sym->file->is_dso && !sym->is_absolute()) {
-- std::scoped_lock lock(sym->mu);
-- sym->is_imported = true;
-+ // If we are using a symbol in a DSO, we need to import it.
-+ if (sym->file && sym->file->is_dso) {
-+ if (!sym->is_absolute()) {
-+ std::scoped_lock lock(sym->mu);
-+ sym->is_imported = true;
-+ }
- continue;
- }
-
-- // If we are creating a DSO, all global symbols are exported by default.
-- if (sym->file == file) {
-- std::scoped_lock lock(sym->mu);
-+ // If we have a definition of a symbol, we may want to export it.
-+ if (sym->file == file && should_export(*sym)) {
- sym->is_exported = true;
-
-- if (ctx.arg.shared && sym->visibility != STV_PROTECTED &&
-+ // Exported symbols are marked as imported as well by default
-+ // for DSOs.
-+ if (ctx.arg.shared &&
-+ sym->visibility != STV_PROTECTED &&
- !ctx.arg.Bsymbolic &&
- !(ctx.arg.Bsymbolic_functions && sym->get_type() == STT_FUNC))
- sym->is_imported = true;
- }
- }
- });
-+
-+
-+ // Apply --dynamic-list, --export-dynamic-symbol and
-+ // --export-dynamic-symbol-list options.
-+ //
-+ // The semantics of these options vary depending on whether we are
-+ // creating an executalbe or a shared object.
-+ //
-+ // For executable, matched symbols are exported.
-+ //
-+ // For shared objects, matched symbols are imported if it is already
-+ // exported so that they are interposable. In other words, symbols
-+ // that did not match will be bound locally within the output file,
-+ // effectively turning them into protected symbols.
-+ MultiGlob matcher;
-+ MultiGlob cpp_matcher;
-+
-+ auto handle_match = [&](Symbol<E> *sym) {
-+ if (ctx.arg.shared) {
-+ if (sym->is_exported)
-+ sym->is_imported = true;
-+ } else {
-+ if (sym->file && !sym->file->is_dso && sym->visibility != STV_HIDDEN)
-+ sym->is_exported = true;
-+ }
-+ };
-+
-+ for (DynamicPattern &p : ctx.dynamic_list_patterns) {
-+ if (p.is_cpp) {
-+ if (!cpp_matcher.add(p.pattern, 1))
-+ Fatal(ctx) << p.source << ": invalid dynamic list entry: "
-+ << p.pattern;
-+ continue;
-+ }
-+
-+ if (p.pattern.find_first_of("*?[") != p.pattern.npos) {
-+ if (!matcher.add(p.pattern, 1))
-+ Fatal(ctx) << p.source << ": invalid dynamic list entry: "
-+ << p.pattern;
-+ continue;
-+ }
-+
-+ handle_match(get_symbol(ctx, p.pattern));
-+ }
-+
-+ if (!matcher.empty() || !cpp_matcher.empty()) {
-+ tbb::parallel_for_each(ctx.objs, [&](ObjectFile<E> *file) {
-+ for (Symbol<E> *sym : file->get_global_syms()) {
-+ if (sym->file != file)
-+ continue;
-+ if (ctx.arg.shared && !sym->is_exported)
-+ continue;
-+
-+ std::string_view name = sym->name();
-+
-+ if (matcher.find(name)) {
-+ handle_match(sym);
-+ } else if (!cpp_matcher.empty()) {
-+ if (std::optional<std::string_view> s = cpp_demangle(name))
-+ name = *s;
-+ if (cpp_matcher.find(name))
-+ handle_match(sym);
-+ }
-+ }
-+ });
-+ }
- }
-
- // Compute the "address-taken" bit for each input section.
-diff --git a/test/elf/dynamic-list4.sh b/test/elf/dynamic-list4.sh
-new file mode 100755
-index 000000000..83d88887e
---- /dev/null
-+++ b/test/elf/dynamic-list4.sh
-@@ -0,0 +1,44 @@
-+#!/bin/bash
-+. $(dirname $0)/common.inc
-+
-+cat <<EOF | $CC -o $t/a.o -c -xc - -fPIC
-+#include <stdio.h>
-+
-+void foo() { printf("foo1 "); }
-+void bar() { printf("bar1 "); }
-+void baz() { printf("baz1 "); }
-+
-+void print() {
-+ foo();
-+ bar();
-+ baz();
-+ printf("\n");
-+}
-+EOF
-+
-+cat <<EOF > $t/dyn
-+{ foo; bar; };
-+EOF
-+
-+$CC -B. -shared -o $t/b.so $t/a.o -Wl,--dynamic-list=$t/dyn
-+
-+cat <<EOF | $CC -o $t/c.o -c -xc - -fPIC
-+#include <stdio.h>
-+void foo() { printf("foo2 "); }
-+void bar() { printf("bar2 "); }
-+void baz() { printf("baz2 "); }
-+EOF
-+
-+$CC -B. -shared -o $t/d.so $t/c.o
-+
-+cat <<EOF | $CC -o $t/e.o -c -xc -
-+#include <stdio.h>
-+void print();
-+int main() { print(); }
-+EOF
-+
-+$CC -B. -o $t/exe1 $t/e.o -Wl,-push-state,-no-as-needed $t/b.so -Wl,-pop-state
-+$QEMU $t/exe1 | grep -q 'foo1 bar1 baz1'
-+
-+$CC -B. -o $t/exe2 $t/e.o -Wl,-push-state,-no-as-needed $t/d.so $t/b.so -Wl,-pop-state
-+$QEMU $t/exe2 | grep -q 'foo2 bar2 baz1'
-diff --git a/test/elf/version-script6.sh b/test/elf/version-script6.sh
-index 74e2f9a89..44f809ef3 100755
---- a/test/elf/version-script6.sh
-+++ b/test/elf/version-script6.sh
-@@ -9,10 +9,10 @@ EOF
- cat <<EOF | $CXX -fPIC -c -o $t/b.o -xc -
- int foo = 5;
- int bar = 6;
-+int quux = 100;
- EOF
-
--$CC -B. -shared -Wl,--version-script=$t/a.ver \
-- -o $t/c.so $t/b.o
-+$CC -B. -shared -Wl,--version-script=$t/a.ver -o $t/c.so $t/b.o
-
- cat <<'EOF' > $t/d.ver
- VER_Y1 { local; *; };