mirror of
https://github.com/rui314/mold.git
synced 2024-12-25 17:34:02 +03:00
temporary
This commit is contained in:
parent
1697c69dd8
commit
45ef22dbdc
2
Makefile
2
Makefile
@ -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
|
||||
|
@ -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
136
main.cc
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user