//===- SyntheticSections.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_MACHO_SYNTHETIC_SECTIONS_H
#define LLD_MACHO_SYNTHETIC_SECTIONS_H

#include "Config.h"
#include "ExportTrie.h"
#include "InputSection.h"
#include "OutputSection.h"
#include "OutputSegment.h"
#include "Target.h"
#include "Writer.h"

#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/Hashing.h"
#include "llvm/ADT/SetVector.h"
#include "llvm/BinaryFormat/MachO.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/raw_ostream.h"

#include <unordered_map>

namespace llvm {
class DWARFUnit;
} // namespace llvm

namespace lld::macho {

class Defined;
class DylibSymbol;
class LoadCommand;
class ObjFile;
class UnwindInfoSection;

class SyntheticSection : public OutputSection {
public:
  SyntheticSection(const char *segname, const char *name);
  virtual ~SyntheticSection() = default;

  static bool classof(const OutputSection *sec) {
    return sec->kind() == SyntheticKind;
  }

  StringRef segname;
  // This fake InputSection makes it easier for us to write code that applies
  // generically to both user inputs and synthetics.
  InputSection *isec;
};

// All sections in __LINKEDIT should inherit from this.
class LinkEditSection : public SyntheticSection {
public:
  LinkEditSection(const char *segname, const char *name)
      : SyntheticSection(segname, name) {
    align = target->wordSize;
  }

  // Implementations of this method can assume that the regular (non-__LINKEDIT)
  // sections already have their addresses assigned.
  virtual void finalizeContents() {}

  // Sections in __LINKEDIT are special: their offsets are recorded in the
  // load commands like LC_DYLD_INFO_ONLY and LC_SYMTAB, instead of in section
  // headers.
  bool isHidden() const final { return true; }

  virtual uint64_t getRawSize() const = 0;

  // codesign (or more specifically libstuff) checks that each section in
  // __LINKEDIT ends where the next one starts -- no gaps are permitted. We
  // therefore align every section's start and end points to WordSize.
  //
  // NOTE: This assumes that the extra bytes required for alignment can be
  // zero-valued bytes.
  uint64_t getSize() const final { return llvm::alignTo(getRawSize(), align); }
};

// The header of the Mach-O file, which must have a file offset of zero.
class MachHeaderSection final : public SyntheticSection {
public:
  MachHeaderSection();
  bool isHidden() const override { return true; }
  uint64_t getSize() const override;
  void writeTo(uint8_t *buf) const override;

  void addLoadCommand(LoadCommand *);

protected:
  std::vector<LoadCommand *> loadCommands;
  uint32_t sizeOfCmds = 0;
};

// A hidden section that exists solely for the purpose of creating the
// __PAGEZERO segment, which is used to catch null pointer dereferences.
class PageZeroSection final : public SyntheticSection {
public:
  PageZeroSection();
  bool isHidden() const override { return true; }
  bool isNeeded() const override { return target->pageZeroSize != 0; }
  uint64_t getSize() const override { return target->pageZeroSize; }
  uint64_t getFileSize() const override { return 0; }
  void writeTo(uint8_t *buf) const override {}
};

// This is the base class for the GOT and TLVPointer sections, which are nearly
// functionally identical -- they will both be populated by dyld with addresses
// to non-lazily-loaded dylib symbols. The main difference is that the
// TLVPointerSection stores references to thread-local variables.
class NonLazyPointerSectionBase : public SyntheticSection {
public:
  NonLazyPointerSectionBase(const char *segname, const char *name);
  const llvm::SetVector<const Symbol *> &getEntries() const { return entries; }
  bool isNeeded() const override { return !entries.empty(); }
  uint64_t getSize() const override {
    return entries.size() * target->wordSize;
  }
  void writeTo(uint8_t *buf) const override;
  void addEntry(Symbol *sym);
  uint64_t getVA(uint32_t gotIndex) const {
    return addr + gotIndex * target->wordSize;
  }

private:
  llvm::SetVector<const Symbol *> entries;
};

class GotSection final : public NonLazyPointerSectionBase {
public:
  GotSection();
};

class TlvPointerSection final : public NonLazyPointerSectionBase {
public:
  TlvPointerSection();
};

struct Location {
  const InputSection *isec;
  uint64_t offset;

  Location(const InputSection *isec, uint64_t offset)
      : isec(isec), offset(offset) {}
  uint64_t getVA() const { return isec->getVA(offset); }
};

// Stores rebase opcodes, which tell dyld where absolute addresses have been
// encoded in the binary. If the binary is not loaded at its preferred address,
// dyld has to rebase these addresses by adding an offset to them.
class RebaseSection final : public LinkEditSection {
public:
  RebaseSection();
  void finalizeContents() override;
  uint64_t getRawSize() const override { return contents.size(); }
  bool isNeeded() const override { return !locations.empty(); }
  void writeTo(uint8_t *buf) const override;

  void addEntry(const InputSection *isec, uint64_t offset) {
    if (config->isPic)
      locations.emplace_back(isec, offset);
  }

private:
  std::vector<Location> locations;
  SmallVector<char, 128> contents;
};

struct BindingEntry {
  int64_t addend;
  Location target;
  BindingEntry(int64_t addend, Location target)
      : addend(addend), target(target) {}
};

template <class Sym>
using BindingsMap = llvm::DenseMap<Sym, std::vector<BindingEntry>>;

// Stores bind opcodes for telling dyld which symbols to load non-lazily.
class BindingSection final : public LinkEditSection {
public:
  BindingSection();
  void finalizeContents() override;
  uint64_t getRawSize() const override { return contents.size(); }
  bool isNeeded() const override { return !bindingsMap.empty(); }
  void writeTo(uint8_t *buf) const override;

  void addEntry(const Symbol *dysym, const InputSection *isec, uint64_t offset,
                int64_t addend = 0) {
    bindingsMap[dysym].emplace_back(addend, Location(isec, offset));
  }

private:
  BindingsMap<const Symbol *> bindingsMap;
  SmallVector<char, 128> contents;
};

// Stores bind opcodes for telling dyld which weak symbols need coalescing.
// There are two types of entries in this section:
//
//   1) Non-weak definitions: This is a symbol definition that weak symbols in
//   other dylibs should coalesce to.
//
//   2) Weak bindings: These tell dyld that a given symbol reference should
//   coalesce to a non-weak definition if one is found. Note that unlike the
//   entries in the BindingSection, the bindings here only refer to these
//   symbols by name, but do not specify which dylib to load them from.
class WeakBindingSection final : public LinkEditSection {
public:
  WeakBindingSection();
  void finalizeContents() override;
  uint64_t getRawSize() const override { return contents.size(); }
  bool isNeeded() const override {
    return !bindingsMap.empty() || !definitions.empty();
  }

  void writeTo(uint8_t *buf) const override;

  void addEntry(const Symbol *symbol, const InputSection *isec, uint64_t offset,
                int64_t addend = 0) {
    bindingsMap[symbol].emplace_back(addend, Location(isec, offset));
  }

  bool hasEntry() const { return !bindingsMap.empty(); }

  void addNonWeakDefinition(const Defined *defined) {
    definitions.emplace_back(defined);
  }

  bool hasNonWeakDefinition() const { return !definitions.empty(); }

private:
  BindingsMap<const Symbol *> bindingsMap;
  std::vector<const Defined *> definitions;
  SmallVector<char, 128> contents;
};

// The following sections implement lazy symbol binding -- very similar to the
// PLT mechanism in ELF.
//
// ELF's .plt section is broken up into two sections in Mach-O: StubsSection
// and StubHelperSection. Calls to functions in dylibs will end up calling into
// StubsSection, which contains indirect jumps to addresses stored in the
// LazyPointerSection (the counterpart to ELF's .plt.got).
//
// We will first describe how non-weak symbols are handled.
//
// At program start, the LazyPointerSection contains addresses that point into
// one of the entry points in the middle of the StubHelperSection. The code in
// StubHelperSection will push on the stack an offset into the
// LazyBindingSection. The push is followed by a jump to the beginning of the
// StubHelperSection (similar to PLT0), which then calls into dyld_stub_binder.
// dyld_stub_binder is a non-lazily-bound symbol, so this call looks it up in
// the GOT.
//
// The stub binder will look up the bind opcodes in the LazyBindingSection at
// the given offset. The bind opcodes will tell the binder to update the
// address in the LazyPointerSection to point to the symbol, so that subsequent
// calls don't have to redo the symbol resolution. The binder will then jump to
// the resolved symbol.
//
// With weak symbols, the situation is slightly different. Since there is no
// "weak lazy" lookup, function calls to weak symbols are always non-lazily
// bound. We emit both regular non-lazy bindings as well as weak bindings, in
// order that the weak bindings may overwrite the non-lazy bindings if an
// appropriate symbol is found at runtime. However, the bound addresses will
// still be written (non-lazily) into the LazyPointerSection.
//
// Symbols are always bound eagerly when chained fixups are used. In that case,
// StubsSection contains indirect jumps to addresses stored in the GotSection.
// The GOT directly contains the fixup entries, which will be replaced by the
// address of the target symbols on load. LazyPointerSection and
// StubHelperSection are not used.

class StubsSection final : public SyntheticSection {
public:
  StubsSection();
  uint64_t getSize() const override;
  bool isNeeded() const override { return !entries.empty(); }
  void finalize() override;
  void writeTo(uint8_t *buf) const override;
  const llvm::SetVector<Symbol *> &getEntries() const { return entries; }
  // Creates a stub for the symbol and the corresponding entry in the
  // LazyPointerSection.
  void addEntry(Symbol *);
  uint64_t getVA(uint32_t stubsIndex) const {
    assert(isFinal || target->usesThunks());
    // ConcatOutputSection::finalize() can seek the address of a
    // stub before its address is assigned. Before __stubs is
    // finalized, return a contrived out-of-range address.
    return isFinal ? addr + stubsIndex * target->stubSize
                   : TargetInfo::outOfRangeVA;
  }

  bool isFinal = false; // is address assigned?

private:
  llvm::SetVector<Symbol *> entries;
};

class StubHelperSection final : public SyntheticSection {
public:
  StubHelperSection();
  uint64_t getSize() const override;
  bool isNeeded() const override;
  void writeTo(uint8_t *buf) const override;

  void setUp();

  DylibSymbol *stubBinder = nullptr;
  Defined *dyldPrivate = nullptr;
};

// Objective-C stubs are hoisted objc_msgSend calls per selector called in the
// program. Apple Clang produces undefined symbols to each stub, such as
// '_objc_msgSend$foo', which are then synthesized by the linker. The stubs
// load the particular selector 'foo' from __objc_selrefs, setting it to the
// first argument of the objc_msgSend call, and then jumps to objc_msgSend. The
// actual stub contents are mirrored from ld64.
class ObjCStubsSection final : public SyntheticSection {
public:
  ObjCStubsSection();
  void initialize();
  void addEntry(Symbol *sym);
  uint64_t getSize() const override;
  bool isNeeded() const override { return !symbols.empty(); }
  void finalize() override { isec->isFinal = true; }
  void writeTo(uint8_t *buf) const override;
  void setUp();

  static constexpr llvm::StringLiteral symbolPrefix = "_objc_msgSend$";
  static bool isObjCStubSymbol(Symbol *sym);
  static StringRef getMethname(Symbol *sym);

private:
  std::vector<Defined *> symbols;
  llvm::DenseMap<llvm::CachedHashStringRef, InputSection *> methnameToSelref;
  Symbol *objcMsgSend = nullptr;
};

// Note that this section may also be targeted by non-lazy bindings. In
// particular, this happens when branch relocations target weak symbols.
class LazyPointerSection final : public SyntheticSection {
public:
  LazyPointerSection();
  uint64_t getSize() const override;
  bool isNeeded() const override;
  void writeTo(uint8_t *buf) const override;
  uint64_t getVA(uint32_t index) const {
    return addr + (index << target->p2WordSize);
  }
};

class LazyBindingSection final : public LinkEditSection {
public:
  LazyBindingSection();
  void finalizeContents() override;
  uint64_t getRawSize() const override { return contents.size(); }
  bool isNeeded() const override { return !entries.empty(); }
  void writeTo(uint8_t *buf) const override;
  // Note that every entry here will by referenced by a corresponding entry in
  // the StubHelperSection.
  void addEntry(Symbol *dysym);
  const llvm::SetVector<Symbol *> &getEntries() const { return entries; }

private:
  uint32_t encode(const Symbol &);

  llvm::SetVector<Symbol *> entries;
  SmallVector<char, 128> contents;
  llvm::raw_svector_ostream os{contents};
};

// Stores a trie that describes the set of exported symbols.
class ExportSection final : public LinkEditSection {
public:
  ExportSection();
  void finalizeContents() override;
  uint64_t getRawSize() const override { return size; }
  bool isNeeded() const override { return size; }
  void writeTo(uint8_t *buf) const override;

  bool hasWeakSymbol = false;

private:
  TrieBuilder trieBuilder;
  size_t size = 0;
};

// Stores 'data in code' entries that describe the locations of data regions
// inside code sections. This is used by llvm-objdump to distinguish jump tables
// and stop them from being disassembled as instructions.
class DataInCodeSection final : public LinkEditSection {
public:
  DataInCodeSection();
  void finalizeContents() override;
  uint64_t getRawSize() const override {
    return sizeof(llvm::MachO::data_in_code_entry) * entries.size();
  }
  void writeTo(uint8_t *buf) const override;

private:
  std::vector<llvm::MachO::data_in_code_entry> entries;
};

// Stores ULEB128 delta encoded addresses of functions.
class FunctionStartsSection final : public LinkEditSection {
public:
  FunctionStartsSection();
  void finalizeContents() override;
  uint64_t getRawSize() const override { return contents.size(); }
  void writeTo(uint8_t *buf) const override;

private:
  SmallVector<char, 128> contents;
};

// Stores the strings referenced by the symbol table.
class StringTableSection final : public LinkEditSection {
public:
  StringTableSection();
  // Returns the start offset of the added string.
  uint32_t addString(StringRef);
  uint64_t getRawSize() const override { return size; }
  void writeTo(uint8_t *buf) const override;

  static constexpr size_t emptyStringIndex = 1;

private:
  // ld64 emits string tables which start with a space and a zero byte. We
  // match its behavior here since some tools depend on it.
  // Consequently, the empty string will be at index 1, not zero.
  std::vector<StringRef> strings{" "};
  size_t size = 2;
};

struct SymtabEntry {
  Symbol *sym;
  size_t strx;
};

struct StabsEntry {
  uint8_t type = 0;
  uint32_t strx = StringTableSection::emptyStringIndex;
  uint8_t sect = 0;
  uint16_t desc = 0;
  uint64_t value = 0;

  StabsEntry() = default;
  explicit StabsEntry(uint8_t type) : type(type) {}
};

// Symbols of the same type must be laid out contiguously: we choose to emit
// all local symbols first, then external symbols, and finally undefined
// symbols. For each symbol type, the LC_DYSYMTAB load command will record the
// range (start index and total number) of those symbols in the symbol table.
class SymtabSection : public LinkEditSection {
public:
  void finalizeContents() override;
  uint32_t getNumSymbols() const;
  uint32_t getNumLocalSymbols() const {
    return stabs.size() + localSymbols.size();
  }
  uint32_t getNumExternalSymbols() const { return externalSymbols.size(); }
  uint32_t getNumUndefinedSymbols() const { return undefinedSymbols.size(); }

private:
  void emitBeginSourceStab(StringRef);
  void emitEndSourceStab();
  void emitObjectFileStab(ObjFile *);
  void emitEndFunStab(Defined *);
  void emitStabs();

protected:
  SymtabSection(StringTableSection &);

  StringTableSection &stringTableSection;
  // STABS symbols are always local symbols, but we represent them with special
  // entries because they may use fields like n_sect and n_desc differently.
  std::vector<StabsEntry> stabs;
  std::vector<SymtabEntry> localSymbols;
  std::vector<SymtabEntry> externalSymbols;
  std::vector<SymtabEntry> undefinedSymbols;
};

template <class LP> SymtabSection *makeSymtabSection(StringTableSection &);

// The indirect symbol table is a list of 32-bit integers that serve as indices
// into the (actual) symbol table. The indirect symbol table is a
// concatenation of several sub-arrays of indices, each sub-array belonging to
// a separate section. The starting offset of each sub-array is stored in the
// reserved1 header field of the respective section.
//
// These sub-arrays provide symbol information for sections that store
// contiguous sequences of symbol references. These references can be pointers
// (e.g. those in the GOT and TLVP sections) or assembly sequences (e.g.
// function stubs).
class IndirectSymtabSection final : public LinkEditSection {
public:
  IndirectSymtabSection();
  void finalizeContents() override;
  uint32_t getNumSymbols() const;
  uint64_t getRawSize() const override {
    return getNumSymbols() * sizeof(uint32_t);
  }
  bool isNeeded() const override;
  void writeTo(uint8_t *buf) const override;
};

// The code signature comes at the very end of the linked output file.
class CodeSignatureSection final : public LinkEditSection {
public:
  // NOTE: These values are duplicated in llvm-objcopy's MachO/Object.h file
  // and any changes here, should be repeated there.
  static constexpr uint8_t blockSizeShift = 12;
  static constexpr size_t blockSize = (1 << blockSizeShift); // 4 KiB
  static constexpr size_t hashSize = 256 / 8;
  static constexpr size_t blobHeadersSize = llvm::alignTo<8>(
      sizeof(llvm::MachO::CS_SuperBlob) + sizeof(llvm::MachO::CS_BlobIndex));
  static constexpr uint32_t fixedHeadersSize =
      blobHeadersSize + sizeof(llvm::MachO::CS_CodeDirectory);

  uint32_t fileNamePad = 0;
  uint32_t allHeadersSize = 0;
  StringRef fileName;

  CodeSignatureSection();
  uint64_t getRawSize() const override;
  bool isNeeded() const override { return true; }
  void writeTo(uint8_t *buf) const override;
  uint32_t getBlockCount() const;
  void writeHashes(uint8_t *buf) const;
};

class CStringSection : public SyntheticSection {
public:
  CStringSection(const char *name);
  void addInput(CStringInputSection *);
  uint64_t getSize() const override { return size; }
  virtual void finalizeContents();
  bool isNeeded() const override { return !inputs.empty(); }
  void writeTo(uint8_t *buf) const override;

  std::vector<CStringInputSection *> inputs;

private:
  uint64_t size;
};

class DeduplicatedCStringSection final : public CStringSection {
public:
  DeduplicatedCStringSection(const char *name) : CStringSection(name){};
  uint64_t getSize() const override { return size; }
  void finalizeContents() override;
  void writeTo(uint8_t *buf) const override;

  struct StringOffset {
    uint8_t trailingZeros;
    uint64_t outSecOff = UINT64_MAX;

    explicit StringOffset(uint8_t zeros) : trailingZeros(zeros) {}
  };

  StringOffset getStringOffset(StringRef str) const;

private:
  llvm::DenseMap<llvm::CachedHashStringRef, StringOffset> stringOffsetMap;
  size_t size = 0;
};

/*
 * This section contains deduplicated literal values. The 16-byte values are
 * laid out first, followed by the 8- and then the 4-byte ones.
 */
class WordLiteralSection final : public SyntheticSection {
public:
  using UInt128 = std::pair<uint64_t, uint64_t>;
  // I don't think the standard guarantees the size of a pair, so let's make
  // sure it's exact -- that way we can construct it via `mmap`.
  static_assert(sizeof(UInt128) == 16);

  WordLiteralSection();
  void addInput(WordLiteralInputSection *);
  void finalizeContents();
  void writeTo(uint8_t *buf) const override;

  uint64_t getSize() const override {
    return literal16Map.size() * 16 + literal8Map.size() * 8 +
           literal4Map.size() * 4;
  }

  bool isNeeded() const override {
    return !literal16Map.empty() || !literal4Map.empty() ||
           !literal8Map.empty();
  }

  uint64_t getLiteral16Offset(uintptr_t buf) const {
    return literal16Map.at(*reinterpret_cast<const UInt128 *>(buf)) * 16;
  }

  uint64_t getLiteral8Offset(uintptr_t buf) const {
    return literal16Map.size() * 16 +
           literal8Map.at(*reinterpret_cast<const uint64_t *>(buf)) * 8;
  }

  uint64_t getLiteral4Offset(uintptr_t buf) const {
    return literal16Map.size() * 16 + literal8Map.size() * 8 +
           literal4Map.at(*reinterpret_cast<const uint32_t *>(buf)) * 4;
  }

private:
  std::vector<WordLiteralInputSection *> inputs;

  template <class T> struct Hasher {
    llvm::hash_code operator()(T v) const { return llvm::hash_value(v); }
  };
  // We're using unordered_map instead of DenseMap here because we need to
  // support all possible integer values -- there are no suitable tombstone
  // values for DenseMap.
  std::unordered_map<UInt128, uint64_t, Hasher<UInt128>> literal16Map;
  std::unordered_map<uint64_t, uint64_t> literal8Map;
  std::unordered_map<uint32_t, uint64_t> literal4Map;
};

class ObjCImageInfoSection final : public SyntheticSection {
public:
  ObjCImageInfoSection();
  bool isNeeded() const override { return !files.empty(); }
  uint64_t getSize() const override { return 8; }
  void addFile(const InputFile *file) {
    assert(!file->objCImageInfo.empty());
    files.push_back(file);
  }
  void finalizeContents();
  void writeTo(uint8_t *buf) const override;

private:
  struct ImageInfo {
    uint8_t swiftVersion = 0;
    bool hasCategoryClassProperties = false;
  } info;
  static ImageInfo parseImageInfo(const InputFile *);
  std::vector<const InputFile *> files; // files with image info
};

// This section stores 32-bit __TEXT segment offsets of initializer functions.
//
// The compiler stores pointers to initializers in __mod_init_func. These need
// to be fixed up at load time, which takes time and dirties memory. By
// synthesizing InitOffsetsSection from them, this data can live in the
// read-only __TEXT segment instead. This section is used by default when
// chained fixups are enabled.
//
// There is no similar counterpart to __mod_term_func, as that section is
// deprecated, and static destructors are instead handled by registering them
// via __cxa_atexit from an autogenerated initializer function (see D121736).
class InitOffsetsSection final : public SyntheticSection {
public:
  InitOffsetsSection();
  bool isNeeded() const override { return !sections.empty(); }
  uint64_t getSize() const override;
  void writeTo(uint8_t *buf) const override;
  void setUp();

  void addInput(ConcatInputSection *isec) { sections.push_back(isec); }
  const std::vector<ConcatInputSection *> &inputs() const { return sections; }

private:
  std::vector<ConcatInputSection *> sections;
};

// Chained fixups are a replacement for classic dyld opcodes. In this format,
// most of the metadata necessary for binding symbols and rebasing addresses is
// stored directly in the memory location that will have the fixup applied.
//
// The fixups form singly linked lists; each one covering a single page in
// memory. The __LINKEDIT,__chainfixups section stores the page offset of the
// first fixup of each page; the rest can be found by walking the chain using
// the offset that is embedded in each entry.
//
// This setup allows pages to be relocated lazily at page-in time and without
// being dirtied. The kernel can discard and load them again as needed. This
// technique, called page-in linking, was introduced in macOS 13.
//
// The benefits of this format are:
//  - smaller __LINKEDIT segment, as most of the fixup information is stored in
//    the data segment
//  - faster startup, since not all relocations need to be done upfront
//  - slightly lower memory usage, as fewer pages are dirtied
//
// Userspace x86_64 and arm64 binaries have two types of fixup entries:
//   - Rebase entries contain an absolute address, to which the object's load
//     address will be added to get the final value. This is used for loading
//     the address of a symbol defined in the same binary.
//   - Binding entries are mostly used for symbols imported from other dylibs,
//     but for weakly bound and interposable symbols as well. They are looked up
//     by a (symbol name, library) pair stored in __chainfixups. This import
//     entry also encodes whether the import is weak (i.e. if the symbol is
//     missing, it should be set to null instead of producing a load error).
//     The fixup encodes an ordinal associated with the import, and an optional
//     addend.
//
// The entries are tightly packed 64-bit bitfields. One of the bits specifies
// which kind of fixup to interpret them as.
//
// LLD generates the fixup data in 5 stages:
//   1. While scanning relocations, we make a note of each location that needs
//      a fixup by calling addRebase() or addBinding(). During this, we assign
//      a unique ordinal for each (symbol name, library, addend) import tuple.
//   2. After addresses have been assigned to all sections, and thus the memory
//      layout of the linked image is final; finalizeContents() is called. Here,
//      the page offsets of the chain start entries are calculated.
//   3. ChainedFixupsSection::writeTo() writes the page start offsets and the
//      imports table to the output file.
//   4. Each section's fixup entries are encoded and written to disk in
//      ConcatInputSection::writeTo(), but without writing the offsets that form
//      the chain.
//   5. Finally, each page's (which might correspond to multiple sections)
//      fixups are linked together in Writer::buildFixupChains().
class ChainedFixupsSection final : public LinkEditSection {
public:
  ChainedFixupsSection();
  void finalizeContents() override;
  uint64_t getRawSize() const override { return size; }
  bool isNeeded() const override;
  void writeTo(uint8_t *buf) const override;

  void addRebase(const InputSection *isec, uint64_t offset) {
    locations.emplace_back(isec, offset);
  }
  void addBinding(const Symbol *dysym, const InputSection *isec,
                  uint64_t offset, int64_t addend = 0);

  void setHasNonWeakDefinition() { hasNonWeakDef = true; }

  // Returns an (ordinal, inline addend) tuple used by dyld_chained_ptr_64_bind.
  std::pair<uint32_t, uint8_t> getBinding(const Symbol *sym,
                                          int64_t addend) const;

  const std::vector<Location> &getLocations() const { return locations; }

  bool hasWeakBinding() const { return hasWeakBind; }
  bool hasNonWeakDefinition() const { return hasNonWeakDef; }

private:
  // Location::offset initially stores the offset within an InputSection, but
  // contains output segment offsets after finalizeContents().
  std::vector<Location> locations;
  // (target symbol, addend) => import ordinal
  llvm::MapVector<std::pair<const Symbol *, int64_t>, uint32_t> bindings;

  struct SegmentInfo {
    SegmentInfo(const OutputSegment *oseg) : oseg(oseg) {}

    const OutputSegment *oseg;
    // (page index, fixup starts offset)
    llvm::SmallVector<std::pair<uint16_t, uint16_t>> pageStarts;

    size_t getSize() const;
    size_t writeTo(uint8_t *buf) const;
  };
  llvm::SmallVector<SegmentInfo, 4> fixupSegments;

  size_t symtabSize = 0;
  size_t size = 0;

  bool needsAddend = false;
  bool needsLargeAddend = false;
  bool hasWeakBind = false;
  bool hasNonWeakDef = false;
  llvm::MachO::ChainedImportFormat importFormat;
};

void writeChainedRebase(uint8_t *buf, uint64_t targetVA);
void writeChainedFixup(uint8_t *buf, const Symbol *sym, int64_t addend);

struct InStruct {
  const uint8_t *bufferStart = nullptr;
  MachHeaderSection *header = nullptr;
  CStringSection *cStringSection = nullptr;
  DeduplicatedCStringSection *objcMethnameSection = nullptr;
  WordLiteralSection *wordLiteralSection = nullptr;
  RebaseSection *rebase = nullptr;
  BindingSection *binding = nullptr;
  WeakBindingSection *weakBinding = nullptr;
  LazyBindingSection *lazyBinding = nullptr;
  ExportSection *exports = nullptr;
  GotSection *got = nullptr;
  TlvPointerSection *tlvPointers = nullptr;
  LazyPointerSection *lazyPointers = nullptr;
  StubsSection *stubs = nullptr;
  StubHelperSection *stubHelper = nullptr;
  ObjCStubsSection *objcStubs = nullptr;
  UnwindInfoSection *unwindInfo = nullptr;
  ObjCImageInfoSection *objCImageInfo = nullptr;
  ConcatInputSection *imageLoaderCache = nullptr;
  InitOffsetsSection *initOffsets = nullptr;
  ChainedFixupsSection *chainedFixups = nullptr;
};

extern InStruct in;
extern std::vector<SyntheticSection *> syntheticSections;

void createSyntheticSymbols();

} // namespace lld::macho

#endif
