1
1
mirror of https://github.com/rui314/mold.git synced 2024-08-17 00:40:36 +03:00
This commit is contained in:
Rui Ueyama 2024-04-13 11:29:47 +09:00
parent 60ce1aaf01
commit 77aefdf6a6
21 changed files with 65 additions and 76 deletions

View File

@ -346,6 +346,7 @@ target_sources(mold PRIVATE
common/filepath.cc common/filepath.cc
common/glob.cc common/glob.cc
common/hyperloglog.cc common/hyperloglog.cc
common/malloc.cc
common/multi-glob.cc common/multi-glob.cc
common/perf.cc common/perf.cc
common/tar.cc common/tar.cc
@ -362,6 +363,7 @@ target_sources(mold PRIVATE
elf/arch-sh4.cc elf/arch-sh4.cc
elf/arch-sparc64.cc elf/arch-sparc64.cc
elf/arch-x86-64.cc elf/arch-x86-64.cc
elf/config.cc
elf/elf.cc elf/elf.cc
git-hash.cc git-hash.cc
third-party/rust-demangle/rust-demangle.c third-party/rust-demangle/rust-demangle.c

View File

@ -401,13 +401,11 @@ inline std::vector<T> flatten(std::vector<std::vector<T>> &vec) {
return ret; return ret;
} }
template <typename T> inline void sort(auto &vec) {
inline void sort(T &vec) {
std::stable_sort(vec.begin(), vec.end()); std::stable_sort(vec.begin(), vec.end());
} }
template <typename T, typename U> inline void sort(auto &vec, auto less) {
inline void sort(T &vec, U less) {
std::stable_sort(vec.begin(), vec.end(), less); std::stable_sort(vec.begin(), vec.end(), less);
} }
@ -535,6 +533,9 @@ inline bool remove_prefix(std::string_view &s, std::string_view prefix) {
// So you need to give a correct estimation of the final size before // So you need to give a correct estimation of the final size before
// using it. We use this hash map to uniquify pieces of data in // using it. We use this hash map to uniquify pieces of data in
// mergeable sections. // mergeable sections.
//
// We've implemented this ourselves because the performance of
// conrurent hash map is critical for our linker.
template <typename T> template <typename T>
class ConcurrentMap { class ConcurrentMap {
public: public:
@ -840,8 +841,7 @@ std::array<u8, 16> get_uuid_v4();
// filepath.cc // filepath.cc
// //
template <typename T> std::filesystem::path filepath(const auto &path) {
std::filesystem::path filepath(const T &path) {
return {path, std::filesystem::path::format::generic_format}; return {path, std::filesystem::path::format::generic_format};
} }

5
common/malloc.cc Normal file
View File

@ -0,0 +1,5 @@
#include "config.h"
#ifdef USE_SYSTEM_MIMALLOC
# include <mimalloc-new-delete.h>
#endif

13
elf/config.cc Normal file
View File

@ -0,0 +1,13 @@
#include "mold.h"
#include "config.h"
namespace mold::elf {
std::string get_mold_version() {
if (mold_git_hash.empty())
return "mold "s + MOLD_VERSION + " (compatible with GNU ld)";
return "mold "s + MOLD_VERSION + " (" + mold_git_hash +
"; compatible with GNU ld)";
}
} // namespace mold::elf

View File

@ -1,15 +1,7 @@
#include "mold.h" #include "mold.h"
#include "config.h"
namespace mold::elf { namespace mold::elf {
std::string get_mold_version() {
if (mold_git_hash.empty())
return "mold "s + MOLD_VERSION + " (compatible with GNU ld)";
return "mold "s + MOLD_VERSION + " (" + mold_git_hash +
"; compatible with GNU ld)";
}
static std::string unknown_type(u32 r_type) { static std::string unknown_type(u32 r_type) {
char buf[50]; char buf[50];
snprintf(buf, sizeof(buf), "unknown (0x%x)", r_type); snprintf(buf, sizeof(buf), "unknown (0x%x)", r_type);

View File

@ -98,22 +98,6 @@ ElfShdr<E> *InputFile<E>::find_section(i64 type) {
return nullptr; return nullptr;
} }
template <typename E>
void InputFile<E>::clear_symbols() {
for (Symbol<E> *sym : get_global_syms()) {
if (__atomic_load_n(&sym->file, __ATOMIC_ACQUIRE) == this) {
sym->origin = 0;
sym->value = -1;
sym->sym_idx = -1;
sym->ver_idx = VER_NDX_UNSPECIFIED;
sym->is_weak = false;
sym->is_imported = false;
sym->is_exported = false;
__atomic_store_n(&sym->file, nullptr, __ATOMIC_RELEASE);
}
}
}
// Find the source filename. It should be listed in symtab as STT_FILE. // Find the source filename. It should be listed in symtab as STT_FILE.
template <typename E> template <typename E>
std::string_view InputFile<E>::get_source_name() const { std::string_view InputFile<E>::get_source_name() const {
@ -1512,7 +1496,7 @@ std::span<Symbol<E> *> SharedFile<E>::find_aliases(Symbol<E> *sym) {
return x->esym().st_value < y->esym().st_value; return x->esym().st_value < y->esym().st_value;
}); });
return {&*begin, &*end}; return {&*begin, (size_t)(end - begin)};
} }
// Infer an alignment of a DSO symbol. An alignment of a symbol in other // Infer an alignment of a DSO symbol. An alignment of a symbol in other

View File

@ -21,8 +21,10 @@
# include <unistd.h> # include <unistd.h>
#endif #endif
#if defined(USE_SYSTEM_MIMALLOC) && defined(MOLD_X86_64) #ifdef MOLD_X86_64
# include <mimalloc-new-delete.h> int main(int argc, char **argv) {
return mold::elf::elf_main<mold::elf::X86_64>(argc, argv);
}
#endif #endif
namespace mold::elf { namespace mold::elf {
@ -718,9 +720,3 @@ using E = MOLD_TARGET;
template int elf_main<E>(int, char **); template int elf_main<E>(int, char **);
} // namespace mold::elf } // namespace mold::elf
#ifdef MOLD_X86_64
int main(int argc, char **argv) {
return mold::elf::elf_main<mold::elf::X86_64>(argc, argv);
}
#endif

View File

@ -54,6 +54,8 @@ static Map<E> get_map(Context<E> &ctx) {
template <typename E> template <typename E>
void print_map(Context<E> &ctx) { void print_map(Context<E> &ctx) {
Timer t(ctx, "print_map");
std::ostream *out = &std::cout; std::ostream *out = &std::cout;
std::unique_ptr<std::ofstream> file; std::unique_ptr<std::ofstream> file;

View File

@ -1100,7 +1100,6 @@ public:
ElfShdr<E> *find_section(i64 type); ElfShdr<E> *find_section(i64 type);
virtual void resolve_symbols(Context<E> &ctx) = 0; virtual void resolve_symbols(Context<E> &ctx) = 0;
void clear_symbols();
virtual void virtual void
mark_live_objects(Context<E> &ctx, mark_live_objects(Context<E> &ctx,
@ -2043,7 +2042,7 @@ public:
// A symbol is owned by a file. If two or more files define the // A symbol is owned by a file. If two or more files define the
// same symbol, the one with the strongest definition owns the symbol. // same symbol, the one with the strongest definition owns the symbol.
// If `file` is null, the symbol is equivalent to nonexistent. // If `file` is null, the symbol is not defined by any input file.
InputFile<E> *file = nullptr; InputFile<E> *file = nullptr;
// A symbol usually belongs to an input section, but it can belong // A symbol usually belongs to an input section, but it can belong

View File

@ -971,7 +971,7 @@ void OutputSection<E>::construct_relr(Context<E> &ctx) {
return; return;
for (const ElfRel<E> &r : isec.get_rels(ctx)) for (const ElfRel<E> &r : isec.get_rels(ctx))
if (r.r_type == E::R_ABS && (r.r_offset % sizeof(Word<E>)) == 0) if (r.r_type == E::R_ABS && r.r_offset % sizeof(Word<E>) == 0)
if (Symbol<E> &sym = *isec.file.symbols[r.r_sym]; if (Symbol<E> &sym = *isec.file.symbols[r.r_sym];
!sym.is_absolute() && !sym.is_imported) !sym.is_absolute() && !sym.is_imported)
shards[i].push_back(isec.offset + r.r_offset); shards[i].push_back(isec.offset + r.r_offset);
@ -2337,8 +2337,8 @@ void CopyrelSection<E>::copy_buf(Context<E> &ctx) {
this->reldyn_offset); this->reldyn_offset);
for (Symbol<E> *sym : symbols) for (Symbol<E> *sym : symbols)
*rel++ = ElfRel<E>(sym->get_addr(ctx), E::R_COPY, sym->get_dynsym_idx(ctx), *rel++ = ElfRel<E>(sym->get_addr(ctx), E::R_COPY,
0); sym->get_dynsym_idx(ctx), 0);
} }
template <typename E> template <typename E>

View File

@ -229,6 +229,28 @@ static void mark_live_objects(Context<E> &ctx) {
}); });
} }
template <typename E>
static void clear_symbols(Context<E> &ctx) {
std::vector<InputFile<E> *> files;
append(files, ctx.objs);
append(files, ctx.dsos);
tbb::parallel_for_each(files, [](InputFile<E> *file) {
for (Symbol<E> *sym : file->get_global_syms()) {
if (__atomic_load_n(&sym->file, __ATOMIC_ACQUIRE) == file) {
sym->origin = 0;
sym->value = -1;
sym->sym_idx = -1;
sym->ver_idx = VER_NDX_UNSPECIFIED;
sym->is_weak = false;
sym->is_imported = false;
sym->is_exported = false;
__atomic_store_n(&sym->file, nullptr, __ATOMIC_RELEASE);
}
}
});
}
template <typename E> template <typename E>
void do_resolve_symbols(Context<E> &ctx) { void do_resolve_symbols(Context<E> &ctx) {
std::vector<InputFile<E> *> files; std::vector<InputFile<E> *> files;
@ -269,9 +291,7 @@ void do_resolve_symbols(Context<E> &ctx) {
// Cleanup. The rule used for archive extraction isn't accurate for the // Cleanup. The rule used for archive extraction isn't accurate for the
// general case of symbol extraction, so reset the resolution to be redone // general case of symbol extraction, so reset the resolution to be redone
// later. // later.
tbb::parallel_for_each(files, [&](InputFile<E> *file) { clear_symbols(ctx);
file->clear_symbols();
});
// Now that the symbol references are gone, remove the eliminated files from // Now that the symbol references are gone, remove the eliminated files from
// the file list. // the file list.
@ -349,13 +369,7 @@ void resolve_symbols(Context<E> &ctx) {
append(ctx.objs, lto_objs); append(ctx.objs, lto_objs);
// Redo name resolution from scratch. // Redo name resolution from scratch.
tbb::parallel_for_each(ctx.objs, [&](ObjectFile<E> *file) { clear_symbols(ctx);
file->clear_symbols();
});
tbb::parallel_for_each(ctx.dsos, [&](SharedFile<E> *file) {
file->clear_symbols();
});
// Remove IR object files. // Remove IR object files.
for (ObjectFile<E> *file : ctx.objs) for (ObjectFile<E> *file : ctx.objs)
@ -864,8 +878,8 @@ void add_synthetic_symbols(Context<E> &ctx) {
} }
if constexpr (is_ppc64v2<E>) if constexpr (is_ppc64v2<E>)
for (auto [label, insn] : ppc64_save_restore_insns) for (std::pair<std::string_view, u32> p : ppc64_save_restore_insns)
if (!label.empty()) if (std::string_view label = p.first; !label.empty())
add(label); add(label);
obj.elf_syms = ctx.internal_esyms; obj.elf_syms = ctx.internal_esyms;
@ -2855,7 +2869,8 @@ void fix_synthetic_symbols(Context<E> &ctx) {
// PPC64's _{save,rest}gpr{0,1}_{14,15,16,...,31} symbols // PPC64's _{save,rest}gpr{0,1}_{14,15,16,...,31} symbols
if constexpr (is_ppc64v2<E>) { if constexpr (is_ppc64v2<E>) {
i64 offset = 0; i64 offset = 0;
for (auto [label, insn] : ppc64_save_restore_insns) { for (std::pair<std::string_view, u32> p : ppc64_save_restore_insns) {
std::string_view label = p.first;
if (!label.empty()) if (!label.empty())
if (Symbol<E> *sym = get_symbol(ctx, label); if (Symbol<E> *sym = get_symbol(ctx, label);
sym->file == ctx.internal_obj) sym->file == ctx.internal_obj)

View File

@ -1,8 +1,6 @@
#!/bin/bash #!/bin/bash
. $(dirname $0)/common.inc . $(dirname $0)/common.inc
[ $MACHINE = aarch64 ] || skip
cat <<EOF | $CC -c -o $t/a.o -fPIC -xassembler - 2> /dev/null || skip cat <<EOF | $CC -c -o $t/a.o -fPIC -xassembler - 2> /dev/null || skip
.global foo .global foo
.type foo, %function .type foo, %function

View File

@ -1,8 +1,6 @@
#!/bin/bash #!/bin/bash
. $(dirname $0)/common.inc . $(dirname $0)/common.inc
[ $MACHINE = arm ] || skip
cat <<EOF | $CC -c -o $t/a.o -fPIC -xc - cat <<EOF | $CC -c -o $t/a.o -fPIC -xc -
#include <stdio.h> #include <stdio.h>

View File

@ -1,8 +1,6 @@
#!/bin/bash #!/bin/bash
. $(dirname $0)/common.inc . $(dirname $0)/common.inc
[ $MACHINE = arm ] || skip
echo 'int main() {}' | $CC -c -o /dev/null -xc - -O0 -mthumb >& /dev/null \ echo 'int main() {}' | $CC -c -o /dev/null -xc - -O0 -mthumb >& /dev/null \
|| skip || skip

View File

@ -1,8 +1,6 @@
#!/bin/bash #!/bin/bash
. $(dirname $0)/common.inc . $(dirname $0)/common.inc
[[ $MACHINE == arm* ]] || skip
echo 'int foo() { return 0; }' | $CC -o /dev/null -c -xc - -mthumb 2> /dev/null || skip echo 'int foo() { return 0; }' | $CC -o /dev/null -c -xc - -mthumb 2> /dev/null || skip
cat <<EOF | $CC -o $t/a.o -c -xc - -mthumb cat <<EOF | $CC -o $t/a.o -c -xc - -mthumb

View File

@ -1,7 +1,6 @@
#!/bin/bash #!/bin/bash
. $(dirname $0)/common.inc . $(dirname $0)/common.inc
[ $MACHINE = arm ] || skip
is_musl && skip is_musl && skip
echo 'int main() {}' | $GCC -c -o /dev/null -xc - -O0 -mthumb >& /dev/null \ echo 'int main() {}' | $GCC -c -o /dev/null -xc - -O0 -mthumb >& /dev/null \

View File

@ -1,8 +1,6 @@
#!/bin/bash #!/bin/bash
. $(dirname $0)/common.inc . $(dirname $0)/common.inc
[ $MACHINE = i686 ] || skip
cat <<'EOF' | $CC -fPIC -o $t/a.o -c -xassembler - cat <<'EOF' | $CC -fPIC -o $t/a.o -c -xassembler -
.globl get_foo .globl get_foo
.type get_foo, @function .type get_foo, @function

View File

@ -1,8 +1,6 @@
#!/bin/bash #!/bin/bash
. $(dirname $0)/common.inc . $(dirname $0)/common.inc
[ $MACHINE = riscv64 -o $MACHINE = riscv32 ] || skip
# Disable C extension # Disable C extension
if [ $MACHINE = riscv32 ]; then if [ $MACHINE = riscv32 ]; then
ISA=rv32g ISA=rv32g

View File

@ -1,8 +1,6 @@
#!/bin/bash #!/bin/bash
. $(dirname $0)/common.inc . $(dirname $0)/common.inc
[[ $MACHINE = riscv* ]] || skip
cat <<EOF | $CC -o $t/a.o -c -xassembler - cat <<EOF | $CC -o $t/a.o -c -xassembler -
.globl get_sym1, get_sym2, get_sym3, get_sym4, get_sym5 .globl get_sym1, get_sym2, get_sym3, get_sym4, get_sym5
.option norvc .option norvc

View File

@ -1,8 +1,6 @@
#!/bin/bash #!/bin/bash
. $(dirname $0)/common.inc . $(dirname $0)/common.inc
[ $MACHINE = riscv64 -o $MACHINE = riscv32 ] || skip
cat <<EOF | $CC -o $t/a.o -c -xassembler - cat <<EOF | $CC -o $t/a.o -c -xassembler -
.globl get_foo, get_foo2, get_bar, get_baz .globl get_foo, get_foo2, get_bar, get_baz
get_foo: get_foo:

View File

@ -1,8 +1,6 @@
#!/bin/bash #!/bin/bash
. $(dirname $0)/common.inc . $(dirname $0)/common.inc
[ $MACHINE = s390x ] || skip
# GOT[0] must be set to the link-time address of .dynamic on s390x. # GOT[0] must be set to the link-time address of .dynamic on s390x.
cat <<EOF | $CC -c -fPIC -o $t/a.o -xc - cat <<EOF | $CC -c -fPIC -o $t/a.o -xc -