// files that are labeled with the same segment and section name. This class
// contains all such sections and writes the data from each section sequentially
// in the final binary.
-class ConcatOutputSection : public OutputSection {
+class ConcatOutputSection final : public OutputSection {
public:
explicit ConcatOutputSection(StringRef name)
: OutputSection(ConcatKind, name) {}
};
// .o file
-class ObjFile : public InputFile {
+class ObjFile final : public InputFile {
public:
ObjFile(MemoryBufferRef mb, uint32_t modTime, StringRef archiveName);
static bool classof(const InputFile *f) { return f->kind() == ObjKind; }
};
// command-line -sectcreate file
-class OpaqueFile : public InputFile {
+class OpaqueFile final : public InputFile {
public:
OpaqueFile(MemoryBufferRef mb, StringRef segName, StringRef sectName);
static bool classof(const InputFile *f) { return f->kind() == OpaqueKind; }
};
// .dylib or .tbd file
-class DylibFile : public InputFile {
+class DylibFile final : public InputFile {
public:
// Mach-O dylibs can re-export other dylibs as sub-libraries, meaning that the
// symbols in those sub-libraries will be available under the umbrella
};
// .a file
-class ArchiveFile : public InputFile {
+class ArchiveFile final : public InputFile {
public:
explicit ArchiveFile(std::unique_ptr<llvm::object::Archive> &&file);
static bool classof(const InputFile *f) { return f->kind() == ArchiveKind; }
llvm::DenseSet<uint64_t> seen;
};
-class BitcodeFile : public InputFile {
+class BitcodeFile final : public InputFile {
public:
explicit BitcodeFile(MemoryBufferRef mb);
static bool classof(const InputFile *f) { return f->kind() == BitcodeKind; }
// ConcatInputSections are combined into (Concat)OutputSections through simple
// concatenation, in contrast with literal sections which may have their
// contents merged before output.
-class ConcatInputSection : public InputSection {
+class ConcatInputSection final : public InputSection {
public:
ConcatInputSection(StringRef segname, StringRef name)
: InputSection(ConcatKind, segname, name) {}
// ld64 is more conservative and does not do that. This was mostly done for
// implementation simplicity; if we find programs that need the more
// conservative behavior we can certainly implement that.
-class CStringInputSection : public InputSection {
+class CStringInputSection final : public InputSection {
public:
CStringInputSection(StringRef segname, StringRef name, InputFile *file,
ArrayRef<uint8_t> data, uint32_t align, uint32_t flags)
std::vector<StringPiece> pieces;
};
-class WordLiteralInputSection : public InputSection {
+class WordLiteralInputSection final : public InputSection {
public:
WordLiteralInputSection(StringRef segname, StringRef name, InputFile *file,
ArrayRef<uint8_t> data, uint32_t align,
}
// This serves to hide (type-erase) the template parameter from SymtabSection.
-template <class LP> class SymtabSectionImpl : public SymtabSection {
+template <class LP> class SymtabSectionImpl final : public SymtabSection {
public:
SymtabSectionImpl(StringTableSection &stringTableSection)
: SymtabSection(stringTableSection) {}
};
// The header of the Mach-O file, which must have a file offset of zero.
-class MachHeaderSection : public SyntheticSection {
+class MachHeaderSection final : public SyntheticSection {
public:
MachHeaderSection();
bool isHidden() const override { return true; }
// A hidden section that exists solely for the purpose of creating the
// __PAGEZERO segment, which is used to catch null pointer dereferences.
-class PageZeroSection : public SyntheticSection {
+class PageZeroSection final : public SyntheticSection {
public:
PageZeroSection();
bool isHidden() const override { return true; }
llvm::SetVector<const Symbol *> entries;
};
-class GotSection : public NonLazyPointerSectionBase {
+class GotSection final : public NonLazyPointerSectionBase {
public:
GotSection()
: NonLazyPointerSectionBase(segment_names::dataConst,
}
};
-class TlvPointerSection : public NonLazyPointerSectionBase {
+class TlvPointerSection final : public NonLazyPointerSectionBase {
public:
TlvPointerSection()
: NonLazyPointerSectionBase(segment_names::data,
// 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 : public LinkEditSection {
+class RebaseSection final : public LinkEditSection {
public:
RebaseSection();
void finalizeContents() override;
};
// Stores bind opcodes for telling dyld which symbols to load non-lazily.
-class BindingSection : public LinkEditSection {
+class BindingSection final : public LinkEditSection {
public:
BindingSection();
void finalizeContents() override;
// 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 : public LinkEditSection {
+class WeakBindingSection final : public LinkEditSection {
public:
WeakBindingSection();
void finalizeContents() override;
// appropriate symbol is found at runtime. However, the bound addresses will
// still be written (non-lazily) into the LazyPointerSection.
-class StubsSection : public SyntheticSection {
+class StubsSection final : public SyntheticSection {
public:
StubsSection();
uint64_t getSize() const override;
llvm::SetVector<Symbol *> entries;
};
-class StubHelperSection : public SyntheticSection {
+class StubHelperSection final : public SyntheticSection {
public:
StubHelperSection();
uint64_t getSize() const override;
// Note that this section may also be targeted by non-lazy bindings. In
// particular, this happens when branch relocations target weak symbols.
-class LazyPointerSection : public SyntheticSection {
+class LazyPointerSection final : public SyntheticSection {
public:
LazyPointerSection();
uint64_t getSize() const override;
void writeTo(uint8_t *buf) const override;
};
-class LazyBindingSection : public LinkEditSection {
+class LazyBindingSection final : public LinkEditSection {
public:
LazyBindingSection();
void finalizeContents() override;
};
// Stores a trie that describes the set of exported symbols.
-class ExportSection : public LinkEditSection {
+class ExportSection final : public LinkEditSection {
public:
ExportSection();
void finalizeContents() override;
};
// Stores ULEB128 delta encoded addresses of functions.
-class FunctionStartsSection : public LinkEditSection {
+class FunctionStartsSection final : public LinkEditSection {
public:
FunctionStartsSection();
void finalizeContents() override;
};
// Stores the strings referenced by the symbol table.
-class StringTableSection : public LinkEditSection {
+class StringTableSection final : public LinkEditSection {
public:
StringTableSection();
// Returns the start offset of the added string.
// 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 : public LinkEditSection {
+class IndirectSymtabSection final : public LinkEditSection {
public:
IndirectSymtabSection();
void finalizeContents() override;
};
// The code signature comes at the very end of the linked output file.
-class CodeSignatureSection : public LinkEditSection {
+class CodeSignatureSection final : public LinkEditSection {
public:
static constexpr uint8_t blockSizeShift = 12;
static constexpr size_t blockSize = (1 << blockSizeShift); // 4 KiB
void writeHashes(uint8_t *buf) const;
};
-class BitcodeBundleSection : public SyntheticSection {
+class BitcodeBundleSection final : public SyntheticSection {
public:
BitcodeBundleSection();
uint64_t getSize() const override { return xarSize; }
uint64_t xarSize;
};
-class CStringSection : public SyntheticSection {
+class CStringSection final : public SyntheticSection {
public:
CStringSection();
void addInput(CStringInputSection *);
* 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 : public SyntheticSection {
+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
};
// LC_DYLD_INFO_ONLY stores the offsets of symbol import/export information.
-class LCDyldInfo : public LoadCommand {
+class LCDyldInfo final : public LoadCommand {
public:
LCDyldInfo(RebaseSection *rebaseSection, BindingSection *bindingSection,
WeakBindingSection *weakBindingSection,
ExportSection *exportSection;
};
-class LCFunctionStarts : public LoadCommand {
+class LCFunctionStarts final : public LoadCommand {
public:
explicit LCFunctionStarts(FunctionStartsSection *functionStartsSection)
: functionStartsSection(functionStartsSection) {}
FunctionStartsSection *functionStartsSection;
};
-class LCDysymtab : public LoadCommand {
+class LCDysymtab final : public LoadCommand {
public:
LCDysymtab(SymtabSection *symtabSection,
IndirectSymtabSection *indirectSymtabSection)
IndirectSymtabSection *indirectSymtabSection;
};
-template <class LP> class LCSegment : public LoadCommand {
+template <class LP> class LCSegment final : public LoadCommand {
public:
LCSegment(StringRef name, OutputSegment *seg) : name(name), seg(seg) {}
OutputSegment *seg;
};
-class LCMain : public LoadCommand {
+class LCMain final : public LoadCommand {
uint32_t getSize() const override {
return sizeof(structs::entry_point_command);
}
}
};
-class LCSymtab : public LoadCommand {
+class LCSymtab final : public LoadCommand {
public:
LCSymtab(SymtabSection *symtabSection, StringTableSection *stringTableSection)
: symtabSection(symtabSection), stringTableSection(stringTableSection) {}
// * LC_LOAD_DYLIB
// * LC_ID_DYLIB
// * LC_REEXPORT_DYLIB
-class LCDylib : public LoadCommand {
+class LCDylib final : public LoadCommand {
public:
LCDylib(LoadCommandType type, StringRef path,
uint32_t compatibilityVersion = 0, uint32_t currentVersion = 0)
uint32_t LCDylib::instanceCount = 0;
-class LCLoadDylinker : public LoadCommand {
+class LCLoadDylinker final : public LoadCommand {
public:
uint32_t getSize() const override {
return alignTo(sizeof(dylinker_command) + path.size() + 1, 8);
const StringRef path = "/usr/lib/dyld";
};
-class LCRPath : public LoadCommand {
+class LCRPath final : public LoadCommand {
public:
explicit LCRPath(StringRef path) : path(path) {}
StringRef path;
};
-class LCMinVersion : public LoadCommand {
+class LCMinVersion final : public LoadCommand {
public:
explicit LCMinVersion(const PlatformInfo &platformInfo)
: platformInfo(platformInfo) {}
const PlatformInfo &platformInfo;
};
-class LCBuildVersion : public LoadCommand {
+class LCBuildVersion final : public LoadCommand {
public:
explicit LCBuildVersion(const PlatformInfo &platformInfo)
: platformInfo(platformInfo) {}
// offsets to be calculated correctly. We resolve this circular paradox by
// first writing an LC_UUID with an all-zero UUID, then updating the UUID with
// its real value later.
-class LCUuid : public LoadCommand {
+class LCUuid final : public LoadCommand {
public:
uint32_t getSize() const override { return sizeof(uuid_command); }
mutable uint8_t *uuidBuf;
};
-template <class LP> class LCEncryptionInfo : public LoadCommand {
+template <class LP> class LCEncryptionInfo final : public LoadCommand {
public:
uint32_t getSize() const override {
return sizeof(typename LP::encryption_info_command);
}
};
-class LCCodeSignature : public LoadCommand {
+class LCCodeSignature final : public LoadCommand {
public:
LCCodeSignature(CodeSignatureSection *section) : section(section) {}