llvm/lld/COFF/Chunks.h

//===- 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