1
1
mirror of https://github.com/rui314/mold.git synced 2024-12-25 17:34:02 +03:00

temporary

This commit is contained in:
Rui Ueyama 2020-11-15 16:19:21 +09:00
parent 1697c69dd8
commit 45ef22dbdc
3 changed files with 94 additions and 57 deletions

View File

@ -7,7 +7,7 @@ LLVM_LIBS=$(wildcard llvm-project/build/lib/libLLVM*.a)
CURRENT_DIR=$(shell pwd)
TBB_LIBDIR=$(wildcard $(CURRENT_DIR)/oneTBB/build/linux_intel64_*_release/)
CPPFLAGS=-g $(shell $(LLVM_CONFIG) --cxxflags) -IoneTBB/include -pthread -std=c++17 -O2
CPPFLAGS=-g $(shell $(LLVM_CONFIG) --cxxflags) -IoneTBB/include -pthread -std=c++17
LDFLAGS=$(shell $(LLVM_CONFIG) --ldflags) -L$(TBB_LIBDIR) -Wl,-rpath=$(TBB_LIBDIR) -fuse-ld=lld -Wl,-hash-style=sysv
LIBS=-pthread -ltbb -lcurses -Wl,--start-group $(LLVM_LIBS) -Wl,--end-group
OBJS=main.o object_file.o input_sections.o output_chunks.o mapfile.o perf.o

View File

@ -35,11 +35,9 @@ void InputSection::copy_to(u8 *buf) {
Symbol &sym = *file->symbols[rel.getSymbol(false)];
u8 *loc = base + rel.r_offset;
u64 G = sym.get_got_addr() - GOT;
u64 S = ref.piece ? ref.piece->get_addr() : sym.get_addr();
u64 A = ref.piece ? ref.addend : rel.r_addend;
u64 P = sh_addr + rel.r_offset;
u64 L = sym.get_plt_addr();
switch (rel.getType(false)) {
case R_X86_64_NONE:
@ -51,16 +49,16 @@ void InputSection::copy_to(u8 *buf) {
*(u32 *)loc = S + A - P;
break;
case R_X86_64_GOT32:
*(u64 *)loc = G + A;
*(u64 *)loc = sym.get_got_addr() - GOT + A;
break;
case R_X86_64_PLT32:
if (config.is_static && sym.type != STT_GNU_IFUNC)
*(u32 *)loc = S + A - P; // todo
else
*(u32 *)loc = L + A - P;
*(u32 *)loc = sym.get_plt_addr() + A - P;
break;
case R_X86_64_GOTPCREL:
*(u32 *)loc = G + GOT + A - P;
*(u32 *)loc = sym.get_got_addr() + A - P;
break;
case R_X86_64_32:
case R_X86_64_32S:
@ -97,7 +95,7 @@ void InputSection::copy_to(u8 *buf) {
break;
case R_X86_64_GOTPCRELX:
case R_X86_64_REX_GOTPCRELX:
*(u32 *)loc = G + GOT + A - P;
*(u32 *)loc = sym.get_got_addr() + A - P;
break;
default:
error(toString(this) + ": unknown relocation: " +
@ -146,8 +144,9 @@ void InputSection::scan_relocations() {
case R_X86_64_TLSLD:
sym->rels |= Symbol::HAS_TLSLD_REL;
break;
case R_X86_64_DTPOFF32:
case R_X86_64_GOTTPOFF:
sym->rels |= Symbol::HAS_GOTTP_REL;
case R_X86_64_DTPOFF32:
case R_X86_64_TPOFF32:
sym->rels |= Symbol::HAS_TPOFF_REL;
break;

136
main.cc
View File

@ -330,6 +330,78 @@ static void set_isec_offsets() {
});
}
static void scan_rels_static(ObjectFile *file) {
for (Symbol *sym : file->symbols) {
if (sym->file != file)
continue;
u8 rels = sym->rels.load(std::memory_order_relaxed);
if (rels & Symbol::HAS_GOT_REL)
sym->got_idx = file->num_got++;
if ((rels & Symbol::HAS_PLT_REL) && sym->type == STT_GNU_IFUNC) {
sym->plt_idx = file->num_plt++;
sym->gotplt_idx = file->num_gotplt++;
sym->relplt_idx = file->num_relplt++;
}
if (rels & Symbol::HAS_TLSGD_REL)
error("not implemented");
if (rels & Symbol::HAS_TLSLD_REL)
error("not implemented");
if (rels & Symbol::HAS_GOTTP_REL)
sym->gottp_idx = file->num_got++;
}
}
static void scan_rels_dynamic(ObjectFile *file) {
for (Symbol *sym : file->symbols) {
if (sym->file != file)
continue;
u8 rels = sym->rels.load(std::memory_order_relaxed);
bool needs_dynsym = false;
if (rels & Symbol::HAS_GOT_REL) {
sym->got_idx = file->num_got++;
file->num_reldyn++;
needs_dynsym = true;
}
if (rels & Symbol::HAS_PLT_REL) {
sym->plt_idx = file->num_plt++;
needs_dynsym = true;
if (sym->got_idx == -1) {
sym->gotplt_idx = file->num_gotplt++;
sym->relplt_idx = file->num_relplt++;
}
}
if (rels & Symbol::HAS_TLSGD_REL) {
sym->gotgd_idx = file->num_got;
file->num_got += 2;
file->num_reldyn += 2;
needs_dynsym = true;
}
if (rels & Symbol::HAS_TLSLD_REL) {
sym->gotgd_idx = file->num_got++;
file->num_reldyn++;
needs_dynsym = true;
}
if (rels & Symbol::HAS_GOTTP_REL)
sym->gottp_idx = file->num_got++;
if (needs_dynsym)
sym->dynsym_idx = file->num_dynsym++;
}
}
static void scan_rels(ArrayRef<ObjectFile *> files) {
MyTimer t("scan_rels", before_copy_timer);
@ -340,52 +412,13 @@ static void scan_rels(ArrayRef<ObjectFile *> files) {
});
tbb::parallel_for_each(files, [&](ObjectFile *file) {
for (Symbol *sym : file->symbols) {
if (sym->file != file)
continue;
u8 rels = sym->rels.load(std::memory_order_relaxed);
bool needs_dynsym = false;
if (rels & Symbol::HAS_GOT_REL) {
sym->got_idx = file->num_got++;
file->num_reldyn++;
needs_dynsym = true;
}
if (rels & Symbol::HAS_PLT_REL) {
sym->plt_idx = file->num_plt++;
needs_dynsym = true;
if (sym->got_idx == -1) {
sym->gotplt_idx = file->num_gotplt++;
sym->relplt_idx = file->num_relplt++;
}
}
if (rels & Symbol::HAS_TLSGD_REL) {
sym->gotgd_idx = file->num_got;
file->num_got += 2;
file->num_reldyn += 2;
needs_dynsym = true;
}
if (rels & Symbol::HAS_TLSLD_REL) {
sym->gotgd_idx = file->num_got++;
file->num_reldyn++;
needs_dynsym = true;
}
if (rels & Symbol::HAS_GOTTP_REL)
sym->gottp_idx = file->num_got++;
if (needs_dynsym)
sym->dynsym_idx = file->num_dynsym++;
}
if (config.is_static)
scan_rels_static(file);
else
scan_rels_dynamic(file);
});
for (ObjectFile *file : files) {
file->got_offset = out::got->shdr.sh_size;
out::got->shdr.sh_size += file->num_got * GOT_SIZE;
@ -398,8 +431,10 @@ static void scan_rels(ArrayRef<ObjectFile *> files) {
file->relplt_offset = out::relplt->shdr.sh_size;
out::relplt->shdr.sh_size += file->num_relplt * sizeof(ELF64LE::Rela);
file->reldyn_offset = out::reldyn->shdr.sh_size;
out::reldyn->shdr.sh_size += file->num_reldyn * sizeof(ELF64LE::Rela);
if (out::reldyn) {
file->reldyn_offset = out::reldyn->shdr.sh_size;
out::reldyn->shdr.sh_size += file->num_reldyn * sizeof(ELF64LE::Rela);
}
file->dynsym_offset = out::dynsym->shdr.sh_size;
out::dynsym->shdr.sh_size += file->num_dynsym * sizeof(ELF64LE::Sym);
@ -425,7 +460,6 @@ static void write_got(u8 *buf, ArrayRef<ObjectFile *> files) {
u8 *gotplt_buf = buf + out::gotplt->shdr.sh_offset + file->gotplt_offset;
u8 *plt_buf = buf + out::plt->shdr.sh_offset + file->plt_offset;
u8 *relplt_buf = buf + out::relplt->shdr.sh_offset + file->relplt_offset;
u8 *reldyn_buf = buf + out::reldyn->shdr.sh_offset + file->reldyn_offset;
u8 *dynsym_buf = buf + out::dynsym->shdr.sh_offset + file->dynsym_offset;
u8 *dynstr_buf = buf + out::dynstr->shdr.sh_offset;
@ -437,9 +471,13 @@ static void write_got(u8 *buf, ArrayRef<ObjectFile *> files) {
continue;
if (sym->got_idx != -1) {
*(u64 *)(got_buf + sym->got_idx * GOT_SIZE) = sym->get_addr();
write_dynamic_rel(reldyn_buf + reldyn_idx++ * sizeof(ELF64LE::Rela),
R_X86_64_GLOB_DAT, sym->get_got_addr(), 0);
if (config.is_static) {
*(u64 *)(got_buf + sym->got_idx * GOT_SIZE) = sym->get_addr();
} else {
u8 *reldyn_buf = buf + out::reldyn->shdr.sh_offset + file->reldyn_offset;
write_dynamic_rel(reldyn_buf + reldyn_idx++ * sizeof(ELF64LE::Rela),
R_X86_64_GLOB_DAT, sym->get_got_addr(), 0);
}
}
if (sym->gottp_idx != -1)