mirror of
https://github.com/rui314/mold.git
synced 2024-08-17 00:40:36 +03:00
Refactor
This commit is contained in:
parent
60ce1aaf01
commit
77aefdf6a6
@ -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
|
||||
|
@ -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
5
common/malloc.cc
Normal file
@ -0,0 +1,5 @@
|
||||
#include "config.h"
|
||||
|
||||
#ifdef USE_SYSTEM_MIMALLOC
|
||||
# include <mimalloc-new-delete.h>
|
||||
#endif
|
13
elf/config.cc
Normal file
13
elf/config.cc
Normal 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
|
@ -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);
|
||||
|
@ -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
|
||||
|
12
elf/main.cc
12
elf/main.cc
@ -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
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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
|
||||
|
@ -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>
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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>
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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 \
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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:
|
||||
|
@ -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 -
|
||||
|
Loading…
Reference in New Issue
Block a user