10b57cec5SDimitry Andric //===- Writer.h -------------------------------------------------*- C++ -*-===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric 90b57cec5SDimitry Andric #ifndef LLD_COFF_WRITER_H 100b57cec5SDimitry Andric #define LLD_COFF_WRITER_H 110b57cec5SDimitry Andric 120b57cec5SDimitry Andric #include "Chunks.h" 130b57cec5SDimitry Andric #include "llvm/ADT/StringRef.h" 140b57cec5SDimitry Andric #include "llvm/Object/COFF.h" 150b57cec5SDimitry Andric #include <chrono> 160b57cec5SDimitry Andric #include <cstdint> 170b57cec5SDimitry Andric #include <vector> 180b57cec5SDimitry Andric 19bdd1243dSDimitry Andric namespace lld::coff { 200b57cec5SDimitry Andric static const int pageSize = 4096; 21349cc55cSDimitry Andric class COFFLinkerContext; 220b57cec5SDimitry Andric 23349cc55cSDimitry Andric void writeResult(COFFLinkerContext &ctx); 240b57cec5SDimitry Andric 250b57cec5SDimitry Andric class PartialSection { 260b57cec5SDimitry Andric public: 270b57cec5SDimitry Andric PartialSection(StringRef n, uint32_t chars) 280b57cec5SDimitry Andric : name(n), characteristics(chars) {} 290b57cec5SDimitry Andric StringRef name; 300b57cec5SDimitry Andric unsigned characteristics; 310b57cec5SDimitry Andric std::vector<Chunk *> chunks; 320b57cec5SDimitry Andric }; 330b57cec5SDimitry Andric 340b57cec5SDimitry Andric // OutputSection represents a section in an output file. It's a 350b57cec5SDimitry Andric // container of chunks. OutputSection and Chunk are 1:N relationship. 360b57cec5SDimitry Andric // Chunks cannot belong to more than one OutputSections. The writer 370b57cec5SDimitry Andric // creates multiple OutputSections and assign them unique, 380b57cec5SDimitry Andric // non-overlapping file offsets and RVAs. 390b57cec5SDimitry Andric class OutputSection { 400b57cec5SDimitry Andric public: 410b57cec5SDimitry Andric OutputSection(llvm::StringRef n, uint32_t chars) : name(n) { 420b57cec5SDimitry Andric header.Characteristics = chars; 430b57cec5SDimitry Andric } 440b57cec5SDimitry Andric void addChunk(Chunk *c); 450b57cec5SDimitry Andric void insertChunkAtStart(Chunk *c); 460b57cec5SDimitry Andric void merge(OutputSection *other); 470b57cec5SDimitry Andric void setPermissions(uint32_t c); 48bdd1243dSDimitry Andric uint64_t getRVA() const { return header.VirtualAddress; } 49bdd1243dSDimitry Andric uint64_t getFileOff() const { return header.PointerToRawData; } 50bdd1243dSDimitry Andric void writeHeaderTo(uint8_t *buf, bool isDebug); 510b57cec5SDimitry Andric void addContributingPartialSection(PartialSection *sec); 520b57cec5SDimitry Andric 530b57cec5SDimitry Andric // Returns the size of this section in an executable memory image. 540b57cec5SDimitry Andric // This may be smaller than the raw size (the raw size is multiple 550b57cec5SDimitry Andric // of disk sector size, so there may be padding at end), or may be 560b57cec5SDimitry Andric // larger (if that's the case, the loader reserves spaces after end 570b57cec5SDimitry Andric // of raw data). 580b57cec5SDimitry Andric uint64_t getVirtualSize() { return header.VirtualSize; } 590b57cec5SDimitry Andric 600b57cec5SDimitry Andric // Returns the size of the section in the output file. 610b57cec5SDimitry Andric uint64_t getRawSize() { return header.SizeOfRawData; } 620b57cec5SDimitry Andric 630b57cec5SDimitry Andric // Set offset into the string table storing this section name. 640b57cec5SDimitry Andric // Used only when the name is longer than 8 bytes. 650b57cec5SDimitry Andric void setStringTableOff(uint32_t v) { stringTableOff = v; } 660b57cec5SDimitry Andric 67*5f757f3fSDimitry Andric bool isCodeSection() const { 68*5f757f3fSDimitry Andric return (header.Characteristics & llvm::COFF::IMAGE_SCN_CNT_CODE) && 69*5f757f3fSDimitry Andric (header.Characteristics & llvm::COFF::IMAGE_SCN_MEM_READ) && 70*5f757f3fSDimitry Andric (header.Characteristics & llvm::COFF::IMAGE_SCN_MEM_EXECUTE); 71*5f757f3fSDimitry Andric } 72*5f757f3fSDimitry Andric 730b57cec5SDimitry Andric // N.B. The section index is one based. 740b57cec5SDimitry Andric uint32_t sectionIndex = 0; 750b57cec5SDimitry Andric 760b57cec5SDimitry Andric llvm::StringRef name; 770b57cec5SDimitry Andric llvm::object::coff_section header = {}; 780b57cec5SDimitry Andric 790b57cec5SDimitry Andric std::vector<Chunk *> chunks; 800b57cec5SDimitry Andric std::vector<Chunk *> origChunks; 810b57cec5SDimitry Andric 820b57cec5SDimitry Andric std::vector<PartialSection *> contribSections; 830b57cec5SDimitry Andric 840b57cec5SDimitry Andric private: 850b57cec5SDimitry Andric uint32_t stringTableOff = 0; 860b57cec5SDimitry Andric }; 870b57cec5SDimitry Andric 88bdd1243dSDimitry Andric } // namespace lld::coff 890b57cec5SDimitry Andric 900b57cec5SDimitry Andric #endif 91