diff --git a/main.cc b/main.cc index aa89e1c9..a74c1dae 100644 --- a/main.cc +++ b/main.cc @@ -150,16 +150,33 @@ static std::vector create_phdrs() { return {}; } -static std::vector +static std::vector create_shdrs(ArrayRef output_chunks) { - std::vector vec; - vec.push_back({}); + static ELF64LE::Shdr null_entry; + + std::vector vec; + vec.push_back(&null_entry); + for (OutputChunk *chunk : output_chunks) if (!chunk->name.empty()) - vec.push_back(chunk->hdr); + vec.push_back(&chunk->hdr); return vec; } +static void fill_shdrs(ArrayRef output_chunks) { + int i = 1; + + for (OutputChunk *chunk : output_chunks) { + if (chunk->name.empty()) + continue; + + chunk->hdr.sh_name = out::shstrtab->add_string(chunk->name); + chunk->hdr.sh_offset = chunk->get_offset(); + chunk->hdr.sh_size = chunk->get_size(); + chunk->index = i++; + } +} + int main(int argc, char **argv) { // Parse command line options MyOptTable opt_table; @@ -260,6 +277,9 @@ int main(int argc, char **argv) { } file_offset_timer.stopTimer(); + // Fill section header. + fill_shdrs(output_chunks); + // Create an output file Expected> buf_or_err = FileOutputBuffer::create(config.output, filesize, 0); diff --git a/mold.h b/mold.h index 4fae3971..7a099090 100644 --- a/mold.h +++ b/mold.h @@ -213,6 +213,7 @@ public: virtual uint64_t get_size() const = 0; StringRef name; + uint32_t index = -1; ELF64LE::Shdr hdr = {}; protected: @@ -235,14 +236,16 @@ public: class OutputShdr : public OutputChunk { public: void copy_to(uint8_t *buf) override { - memcpy(buf + offset, &hdr[0], get_size()); + auto *p = (ELF64LE::Shdr *)(buf + offset); + for (ELF64LE::Shdr *x : hdr) + *p++ = *x; } uint64_t get_size() const override { return hdr.size() * sizeof(hdr[0]); } - std::vector hdr; + std::vector hdr; }; // Program header @@ -280,8 +283,8 @@ public: } uint64_t get_size() const override { - assert(size >= 0); - return size; + return chunks.back()->offset + chunks.back()->get_size() - + chunks.front()->offset; } void set_offset(uint64_t off) override; @@ -291,7 +294,6 @@ public: private: uint64_t file_offset = 0; - uint64_t on_file_size = -1; }; class InterpSection : public OutputChunk { @@ -321,12 +323,12 @@ public: hdr.sh_type = llvm::ELF::SHT_STRTAB; } - uint64_t addString(StringRef s); + uint64_t add_string(StringRef s); void copy_to(uint8_t *buf) override; uint64_t get_size() const override { return contents.size(); } private: - std::string contents; + std::string contents = "\0"; }; namespace out { @@ -340,7 +342,7 @@ extern StringTableSection *shstrtab; // input_files.cc // -class ObjectFile { +class ObjectFile { public: ObjectFile(MemoryBufferRef mb, StringRef archive_name); diff --git a/output_chunks.cc b/output_chunks.cc index ac3f9523..89665abc 100644 --- a/output_chunks.cc +++ b/output_chunks.cc @@ -29,7 +29,7 @@ void OutputEhdr::relocate(uint8_t *buf) { hdr->e_phnum = out::phdr->hdr.size(); hdr->e_shentsize = sizeof(ELF64LE::Shdr); hdr->e_shnum = out::shdr->hdr.size(); - hdr->e_shstrndx = 0; + hdr->e_shstrndx = out::shstrtab->index; } void OutputSection::set_offset(uint64_t off) { @@ -79,7 +79,7 @@ OutputSection *OutputSection::get_instance(InputSection *isec) { return new OutputSection(iname, iflags, isec->hdr->sh_type); } -uint64_t StringTableSection::addString(StringRef s) { +uint64_t StringTableSection::add_string(StringRef s) { uint64_t ret = contents.size(); contents += s.str(); contents += "\0";