//===- Chunks.h -------------------------------------------------*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// #ifndef LLD_COFF_CHUNKS_H #define LLD_COFF_CHUNKS_H #include "Config.h" #include "InputFiles.h" #include "lld/Common/LLVM.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/PointerIntPair.h" #include "llvm/ADT/iterator.h" #include "llvm/ADT/iterator_range.h" #include "llvm/MC/StringTableBuilder.h" #include "llvm/Object/COFF.h" #include "llvm/Object/WindowsMachineFlag.h" #include <utility> #include <vector> namespace lld::coff { ImportDirectoryTableEntry; chpe_range_type; coff_relocation; coff_section; COFFSymbolRef; SectionRef; class Baserel; class Defined; class DefinedImportData; class DefinedRegular; class ObjFile; class OutputSection; class RuntimePseudoReloc; class Symbol; // Mask for permissions (discardable, writable, readable, executable, etc). const uint32_t permMask = …; // Mask for section types (code, data, bss). const uint32_t typeMask = …; // The log base 2 of the largest section alignment, which is log2(8192), or 13. enum : unsigned { … }; // A Chunk represents a chunk of data that will occupy space in the // output (if the resolver chose that). It may or may not be backed by // a section of an input file. It could be linker-created data, or // doesn't even have actual data (if common or bss). class Chunk { … }; class NonSectionChunk : public Chunk { … }; class NonSectionCodeChunk : public NonSectionChunk { … }; // MinGW specific; information about one individual location in the image // that needs to be fixed up at runtime after loading. This represents // one individual element in the PseudoRelocTableChunk table. class RuntimePseudoReloc { … }; // A chunk corresponding a section of an input file. class SectionChunk : public Chunk { … }; // A section chunk corresponding a section of an EC input file. class SectionChunkEC final : public SectionChunk { … }; // Inline methods to implement faux-virtual dispatch for SectionChunk. inline size_t Chunk::getSize() const { … } inline uint32_t Chunk::getOutputCharacteristics() const { … } inline void Chunk::writeTo(uint8_t *buf) const { … } inline StringRef Chunk::getSectionName() const { … } inline void Chunk::getBaserels(std::vector<Baserel> *res) { … } inline StringRef Chunk::getDebugName() const { … } inline MachineTypes Chunk::getMachine() const { … } inline llvm::Triple::ArchType Chunk::getArch() const { … } inline std::optional<chpe_range_type> Chunk::getArm64ECRangeType() const { … } // This class is used to implement an lld-specific feature (not implemented in // MSVC) that minimizes the output size by finding string literals sharing tail // parts and merging them. // // If string tail merging is enabled and a section is identified as containing a // string literal, it is added to a MergeChunk with an appropriate alignment. // The MergeChunk then tail merges the strings using the StringTableBuilder // class and assigns RVAs and section offsets to each of the member chunks based // on the offsets assigned by the StringTableBuilder. class MergeChunk : public NonSectionChunk { … }; // A chunk for common symbols. Common chunks don't have actual data. class CommonChunk : public NonSectionChunk { … }; // A chunk for linker-created strings. class StringChunk : public NonSectionChunk { … }; static const uint8_t importThunkX86[] = …; static const uint8_t importThunkARM[] = …; static const uint8_t importThunkARM64[] = …; static const uint8_t importThunkARM64EC[] = …; // Windows-specific. // A chunk for DLL import jump table entry. In a final output, its // contents will be a JMP instruction to some __imp_ symbol. class ImportThunkChunk : public NonSectionCodeChunk { … }; class ImportThunkChunkX64 : public ImportThunkChunk { … }; class ImportThunkChunkX86 : public ImportThunkChunk { … }; class ImportThunkChunkARM : public ImportThunkChunk { … }; class ImportThunkChunkARM64 : public ImportThunkChunk { … }; // ARM64EC __impchk_* thunk implementation. // Performs an indirect call to an imported function pointer // using the __icall_helper_arm64ec helper function. class ImportThunkChunkARM64EC : public ImportThunkChunk { … }; class RangeExtensionThunkARM : public NonSectionCodeChunk { … }; // A ragnge extension thunk used for both ARM64EC and ARM64 machine types. class RangeExtensionThunkARM64 : public NonSectionCodeChunk { … }; // Windows-specific. // See comments for DefinedLocalImport class. class LocalImportChunk : public NonSectionChunk { … }; // Duplicate RVAs are not allowed in RVA tables, so unique symbols by chunk and // offset into the chunk. Order does not matter as the RVA table will be sorted // later. struct ChunkAndOffset { … }; SymbolRVASet; // Table which contains symbol RVAs. Used for /safeseh and /guard:cf. class RVATableChunk : public NonSectionChunk { … }; // Table which contains symbol RVAs with flags. Used for /guard:ehcont. class RVAFlagTableChunk : public NonSectionChunk { … }; // Windows-specific. // This class represents a block in .reloc section. // See the PE/COFF spec 5.6 for details. class BaserelChunk : public NonSectionChunk { … }; class Baserel { … }; // This is a placeholder Chunk, to allow attaching a DefinedSynthetic to a // specific place in a section, without any data. This is used for the MinGW // specific symbol __RUNTIME_PSEUDO_RELOC_LIST_END__, even though the concept // of an empty chunk isn't MinGW specific. class EmptyChunk : public NonSectionChunk { … }; class ECCodeMapEntry { … }; // This is a chunk containing CHPE code map on EC targets. It's a table // of address ranges and their types. class ECCodeMapChunk : public NonSectionChunk { … }; class CHPECodeRangesChunk : public NonSectionChunk { … }; class CHPERedirectionChunk : public NonSectionChunk { … }; static const uint8_t ECExportThunkCode[] = …; class ECExportThunkChunk : public NonSectionCodeChunk { … }; // MinGW specific, for the "automatic import of variables from DLLs" feature. // This provides the table of runtime pseudo relocations, for variable // references that turned out to need to be imported from a DLL even though // the reference didn't use the dllimport attribute. The MinGW runtime will // process this table after loading, before handling control over to user // code. class PseudoRelocTableChunk : public NonSectionChunk { … }; // MinGW specific. A Chunk that contains one pointer-sized absolute value. class AbsolutePointerChunk : public NonSectionChunk { … }; // Return true if this file has the hotpatch flag set to true in the S_COMPILE3 // record in codeview debug info. Also returns true for some thunks synthesized // by the linker. inline bool Chunk::isHotPatchable() const { … } inline Defined *Chunk::getEntryThunk() const { … } inline void Chunk::setEntryThunk(Defined *entryThunk) { … } void applyMOV32T(uint8_t *off, uint32_t v); void applyBranch24T(uint8_t *off, int32_t v); void applyArm64Addr(uint8_t *off, uint64_t s, uint64_t p, int shift); void applyArm64Imm(uint8_t *off, uint64_t imm, uint32_t rangeLimit); void applyArm64Branch26(uint8_t *off, int64_t v); // Convenience class for initializing a coff_section with specific flags. class FakeSection { … }; // Convenience class for initializing a SectionChunk with specific flags. class FakeSectionChunk { … }; } // namespace lld::coff namespace llvm { template <> struct DenseMapInfo<lld::coff::ChunkAndOffset> : lld::coff::ChunkAndOffset::DenseMapInfo { … }; } #endif