1
1
mirror of https://github.com/rui314/mold.git synced 2024-07-14 16:20:34 +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/glob.cc
common/hyperloglog.cc
common/malloc.cc
common/multi-glob.cc
common/perf.cc
common/tar.cc
@ -362,6 +363,7 @@ target_sources(mold PRIVATE
elf/arch-sh4.cc
elf/arch-sparc64.cc
elf/arch-x86-64.cc
elf/config.cc
elf/elf.cc
git-hash.cc
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;
}
template <typename T>
inline void sort(T &vec) {
inline void sort(auto &vec) {
std::stable_sort(vec.begin(), vec.end());
}
template <typename T, typename U>
inline void sort(T &vec, U less) {
inline void sort(auto &vec, auto 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
// using it. We use this hash map to uniquify pieces of data in
// mergeable sections.
//
// We've implemented this ourselves because the performance of
// conrurent hash map is critical for our linker.
template <typename T>
class ConcurrentMap {
public:
@ -840,8 +841,7 @@ std::array<u8, 16> get_uuid_v4();
// filepath.cc
//
template <typename T>
std::filesystem::path filepath(const T &path) {
std::filesystem::path filepath(const auto &path) {
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 "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)";
}
static std::string unknown_type(u32 r_type) {
char buf[50];
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;
}
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.
template <typename E>
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 {&*begin, &*end};
return {&*begin, (size_t)(end - begin)};
}
// Infer an alignment of a DSO symbol. An alignment of a symbol in other

View File

@ -21,8 +21,10 @@
# include <unistd.h>
#endif
#if defined(USE_SYSTEM_MIMALLOC) && defined(MOLD_X86_64)
# include <mimalloc-new-delete.h>
#ifdef MOLD_X86_64
int main(int argc, char **argv) {
return mold::elf::elf_main<mold::elf::X86_64>(argc, argv);
}
#endif
namespace mold::elf {
@ -718,9 +720,3 @@ using E = MOLD_TARGET;
template int elf_main<E>(int, char **);
} // 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>
void print_map(Context<E> &ctx) {
Timer t(ctx, "print_map");
std::ostream *out = &std::cout;
std::unique_ptr<std::ofstream> file;

View File

@ -1100,7 +1100,6 @@ public:
ElfShdr<E> *find_section(i64 type);
virtual void resolve_symbols(Context<E> &ctx) = 0;
void clear_symbols();
virtual void
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
// 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;
// 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;
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];
!sym.is_absolute() && !sym.is_imported)
shards[i].push_back(isec.offset + r.r_offset);
@ -2337,8 +2337,8 @@ void CopyrelSection<E>::copy_buf(Context<E> &ctx) {
this->reldyn_offset);
for (Symbol<E> *sym : symbols)
*rel++ = ElfRel<E>(sym->get_addr(ctx), E::R_COPY, sym->get_dynsym_idx(ctx),
0);
*rel++ = ElfRel<E>(sym->get_addr(ctx), E::R_COPY,
sym->get_dynsym_idx(ctx), 0);
}
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>
void do_resolve_symbols(Context<E> &ctx) {
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
// general case of symbol extraction, so reset the resolution to be redone
// later.
tbb::parallel_for_each(files, [&](InputFile<E> *file) {
file->clear_symbols();
});
clear_symbols(ctx);
// Now that the symbol references are gone, remove the eliminated files from
// the file list.
@ -349,13 +369,7 @@ void resolve_symbols(Context<E> &ctx) {
append(ctx.objs, lto_objs);
// Redo name resolution from scratch.
tbb::parallel_for_each(ctx.objs, [&](ObjectFile<E> *file) {
file->clear_symbols();
});
tbb::parallel_for_each(ctx.dsos, [&](SharedFile<E> *file) {
file->clear_symbols();
});
clear_symbols(ctx);
// Remove IR object files.
for (ObjectFile<E> *file : ctx.objs)
@ -864,8 +878,8 @@ void add_synthetic_symbols(Context<E> &ctx) {
}
if constexpr (is_ppc64v2<E>)
for (auto [label, insn] : ppc64_save_restore_insns)
if (!label.empty())
for (std::pair<std::string_view, u32> p : ppc64_save_restore_insns)
if (std::string_view label = p.first; !label.empty())
add(label);
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
if constexpr (is_ppc64v2<E>) {
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 (Symbol<E> *sym = get_symbol(ctx, label);
sym->file == ctx.internal_obj)

View File

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

View File

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

View File

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

View File

@ -1,8 +1,6 @@
#!/bin/bash
. $(dirname $0)/common.inc
[[ $MACHINE == arm* ]] || 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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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