From e260e8dc5b02ba66e9078d774d05828b77ae0a8d Mon Sep 17 00:00:00 2001 From: Rui Ueyama Date: Fri, 30 Oct 2020 11:40:38 +0900 Subject: [PATCH] temporary --- input_sections.cc | 5 +++-- main.cc | 37 ++++++++++++++++++++++++------------- mold.h | 5 +++++ output_chunks.cc | 3 ++- 4 files changed, 34 insertions(+), 16 deletions(-) diff --git a/input_sections.cc b/input_sections.cc index f6a9d7aa..2dbe4d0c 100644 --- a/input_sections.cc +++ b/input_sections.cc @@ -68,7 +68,7 @@ void InputSection::relocate(u8 *buf) { u64 P = output_section->shdr.sh_addr + offset + rel.r_offset; u64 S = sym ? sym->addr : file->get_symbol_addr(sym_idx); - u64 A = rel.r_addend; + i64 A = rel.r_addend; u64 G = sym ? sym->got_addr : 0; u64 GOT = out::got->shdr.sh_addr; @@ -85,7 +85,8 @@ void InputSection::relocate(u8 *buf) { *(u64 *)loc = G + A; break; case R_X86_64_PLT32: - break; // todo + *(u32 *)loc = S + A - P; // todo + break; case R_X86_64_GOTPCREL: *(u32 *)loc = G + GOT + A - P; break; diff --git a/main.cc b/main.cc index 3165c26a..95545162 100644 --- a/main.cc +++ b/main.cc @@ -291,13 +291,15 @@ static u64 set_osec_offsets(ArrayRef output_chunks) { u64 vaddr = 0x200000; for (OutputChunk *chunk : output_chunks) { - if (chunk->starts_new_ptload) { - fileoff = align_to(fileoff, PAGE_SIZE); + if (chunk->starts_new_ptload) vaddr = align_to(vaddr, PAGE_SIZE); - } - if (!chunk->is_bss()) - fileoff = align_to(fileoff, chunk->shdr.sh_addralign); + if (vaddr % PAGE_SIZE < fileoff % PAGE_SIZE) + fileoff += vaddr % PAGE_SIZE - fileoff % PAGE_SIZE; + else if (vaddr % PAGE_SIZE > fileoff % PAGE_SIZE) + fileoff = align_to(fileoff, PAGE_SIZE) + vaddr % PAGE_SIZE; + + fileoff = align_to(fileoff, chunk->shdr.sh_addralign); vaddr = align_to(vaddr, chunk->shdr.sh_addralign); chunk->shdr.sh_offset = fileoff; @@ -306,7 +308,10 @@ static u64 set_osec_offsets(ArrayRef output_chunks) { if (!chunk->is_bss()) fileoff += chunk->get_size(); - vaddr += chunk->get_size(); + + bool is_tbss = chunk->is_bss() && (chunk->shdr.sh_flags & SHF_TLS); + if (!is_tbss) + vaddr += chunk->get_size(); } return fileoff; } @@ -506,7 +511,7 @@ int main(int argc, char **argv) { for (ObjectFile *file : files) { for (Symbol *sym : file->symbols) { - if (sym->file == file && sym->needs_got) { + if (sym->file == file && sym->needs_got) { out::got->symbols.push_back(sym); sym->got_addr = offset; offset += 8; @@ -575,14 +580,20 @@ int main(int argc, char **argv) { } // Create an output file - Expected> buf_or_err = - FileOutputBuffer::create(config.output, filesize, FileOutputBuffer::F_executable); + std::unique_ptr output_buffer; - if (!buf_or_err) - error("failed to open " + config.output + ": " + - llvm::toString(buf_or_err.takeError())); + { + MyTimer t("open"); + Expected> buf_or_err = + FileOutputBuffer::create(config.output, filesize, FileOutputBuffer::F_executable); + + if (!buf_or_err) + error("failed to open " + config.output + ": " + + llvm::toString(buf_or_err.takeError())); + + output_buffer = std::move(*buf_or_err); + } - std::unique_ptr output_buffer = std::move(*buf_or_err); u8 *buf = output_buffer->getBufferStart(); // Fill .symtab and .strtab diff --git a/mold.h b/mold.h index a493c8f7..2ca48fa0 100644 --- a/mold.h +++ b/mold.h @@ -50,6 +50,11 @@ typedef uint16_t u16; typedef uint32_t u32; typedef uint64_t u64; +typedef int8_t i8; +typedef int16_t i16; +typedef int32_t i32; +typedef int64_t i64; + using llvm::ArrayRef; using llvm::ErrorOr; using llvm::Error; diff --git a/output_chunks.cc b/output_chunks.cc index 22f85a2f..45942f21 100644 --- a/output_chunks.cc +++ b/output_chunks.cc @@ -72,7 +72,8 @@ void OutputPhdr::construct(std::vector &chunks) { break; u32 flags = to_phdr_flags(chunk->shdr.sh_flags); - bool this_is_bss = (chunk->shdr.sh_type == SHT_NOBITS); + bool this_is_bss = + (chunk->shdr.sh_type == SHT_NOBITS && !(chunk->shdr.sh_flags & SHF_TLS)); if (first) { add(PT_LOAD, flags, {chunk});