15ffd83dbSDimitry Andric //===- InputSection.h -------------------------------------------*- C++ -*-===// 25ffd83dbSDimitry Andric // 35ffd83dbSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 45ffd83dbSDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 55ffd83dbSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 65ffd83dbSDimitry Andric // 75ffd83dbSDimitry Andric //===----------------------------------------------------------------------===// 85ffd83dbSDimitry Andric 95ffd83dbSDimitry Andric #ifndef LLD_MACHO_INPUT_SECTION_H 105ffd83dbSDimitry Andric #define LLD_MACHO_INPUT_SECTION_H 115ffd83dbSDimitry Andric 12fe6060f1SDimitry Andric #include "Config.h" 13fe6060f1SDimitry Andric #include "Relocations.h" 14349cc55cSDimitry Andric #include "Symbols.h" 15fe6060f1SDimitry Andric 165ffd83dbSDimitry Andric #include "lld/Common/LLVM.h" 17fe6060f1SDimitry Andric #include "lld/Common/Memory.h" 185ffd83dbSDimitry Andric #include "llvm/ADT/ArrayRef.h" 19fe6060f1SDimitry Andric #include "llvm/ADT/BitVector.h" 20fe6060f1SDimitry Andric #include "llvm/ADT/CachedHashString.h" 21349cc55cSDimitry Andric #include "llvm/ADT/TinyPtrVector.h" 225ffd83dbSDimitry Andric #include "llvm/BinaryFormat/MachO.h" 235ffd83dbSDimitry Andric 245ffd83dbSDimitry Andric namespace lld { 255ffd83dbSDimitry Andric namespace macho { 265ffd83dbSDimitry Andric 275ffd83dbSDimitry Andric class InputFile; 285ffd83dbSDimitry Andric class OutputSection; 295ffd83dbSDimitry Andric 305ffd83dbSDimitry Andric class InputSection { 315ffd83dbSDimitry Andric public: 3281ad6265SDimitry Andric enum Kind : uint8_t { 33fe6060f1SDimitry Andric ConcatKind, 34fe6060f1SDimitry Andric CStringLiteralKind, 35fe6060f1SDimitry Andric WordLiteralKind, 36fe6060f1SDimitry Andric }; 37fe6060f1SDimitry Andric 3881ad6265SDimitry Andric Kind kind() const { return sectionKind; } 395ffd83dbSDimitry Andric virtual ~InputSection() = default; 405ffd83dbSDimitry Andric virtual uint64_t getSize() const { return data.size(); } 41349cc55cSDimitry Andric virtual bool empty() const { return data.empty(); } 4281ad6265SDimitry Andric InputFile *getFile() const { return section.file; } 4381ad6265SDimitry Andric StringRef getName() const { return section.name; } 4481ad6265SDimitry Andric StringRef getSegName() const { return section.segname; } 4581ad6265SDimitry Andric uint32_t getFlags() const { return section.flags; } 46fe6060f1SDimitry Andric uint64_t getFileSize() const; 47fe6060f1SDimitry Andric // Translates \p off -- an offset relative to this InputSection -- into an 48fe6060f1SDimitry Andric // offset from the beginning of its parent OutputSection. 49fe6060f1SDimitry Andric virtual uint64_t getOffset(uint64_t off) const = 0; 50fe6060f1SDimitry Andric // The offset from the beginning of the file. 51fe6060f1SDimitry Andric uint64_t getVA(uint64_t off) const; 5281ad6265SDimitry Andric // Return a user-friendly string for use in diagnostics. 5381ad6265SDimitry Andric // Format: /path/to/object.o:(symbol _func+0x123) 5481ad6265SDimitry Andric std::string getLocation(uint64_t off) const; 5581ad6265SDimitry Andric // Return the source line corresponding to an address, or the empty string. 5681ad6265SDimitry Andric // Format: Source.cpp:123 (/path/to/Source.cpp:123) 5781ad6265SDimitry Andric std::string getSourceLocation(uint64_t off) const; 58*06c3fb27SDimitry Andric // Return the relocation at \p off, if it exists. This does a linear search. 59*06c3fb27SDimitry Andric const Reloc *getRelocAt(uint32_t off) const; 60fe6060f1SDimitry Andric // Whether the data at \p off in this InputSection is live. 61fe6060f1SDimitry Andric virtual bool isLive(uint64_t off) const = 0; 62fe6060f1SDimitry Andric virtual void markLive(uint64_t off) = 0; 63fe6060f1SDimitry Andric virtual InputSection *canonical() { return this; } 6404eeddc0SDimitry Andric virtual const InputSection *canonical() const { return this; } 655ffd83dbSDimitry Andric 6681ad6265SDimitry Andric protected: 6781ad6265SDimitry Andric InputSection(Kind kind, const Section §ion, ArrayRef<uint8_t> data, 6881ad6265SDimitry Andric uint32_t align) 69bdd1243dSDimitry Andric : sectionKind(kind), keepUnique(false), hasAltEntry(false), align(align), 70bdd1243dSDimitry Andric data(data), section(section) {} 715ffd83dbSDimitry Andric 7281ad6265SDimitry Andric InputSection(const InputSection &rhs) 73bdd1243dSDimitry Andric : sectionKind(rhs.sectionKind), keepUnique(false), hasAltEntry(false), 74bdd1243dSDimitry Andric align(rhs.align), data(rhs.data), section(rhs.section) {} 7581ad6265SDimitry Andric 7681ad6265SDimitry Andric Kind sectionKind; 7781ad6265SDimitry Andric 7881ad6265SDimitry Andric public: 79fe6060f1SDimitry Andric // is address assigned? 800eae32dcSDimitry Andric bool isFinal = false; 8181ad6265SDimitry Andric // keep the address of the symbol(s) in this section unique in the final 8281ad6265SDimitry Andric // binary ? 83bdd1243dSDimitry Andric bool keepUnique : 1; 84bdd1243dSDimitry Andric // Does this section have symbols at offsets other than zero? (NOTE: only 85bdd1243dSDimitry Andric // applies to ConcatInputSections.) 86bdd1243dSDimitry Andric bool hasAltEntry : 1; 8781ad6265SDimitry Andric uint32_t align = 1; 885ffd83dbSDimitry Andric 8981ad6265SDimitry Andric OutputSection *parent = nullptr; 905ffd83dbSDimitry Andric ArrayRef<uint8_t> data; 915ffd83dbSDimitry Andric std::vector<Reloc> relocs; 92349cc55cSDimitry Andric // The symbols that belong to this InputSection, sorted by value. With 93349cc55cSDimitry Andric // .subsections_via_symbols, there is typically only one element here. 94349cc55cSDimitry Andric llvm::TinyPtrVector<Defined *> symbols; 95fe6060f1SDimitry Andric 96fe6060f1SDimitry Andric protected: 9781ad6265SDimitry Andric const Section §ion; 98fe6060f1SDimitry Andric 9981ad6265SDimitry Andric const Defined *getContainingSymbol(uint64_t off) const; 100fe6060f1SDimitry Andric }; 101fe6060f1SDimitry Andric 102fe6060f1SDimitry Andric // ConcatInputSections are combined into (Concat)OutputSections through simple 103fe6060f1SDimitry Andric // concatenation, in contrast with literal sections which may have their 104fe6060f1SDimitry Andric // contents merged before output. 105fe6060f1SDimitry Andric class ConcatInputSection final : public InputSection { 106fe6060f1SDimitry Andric public: 10781ad6265SDimitry Andric ConcatInputSection(const Section §ion, ArrayRef<uint8_t> data, 10881ad6265SDimitry Andric uint32_t align = 1) 10981ad6265SDimitry Andric : InputSection(ConcatKind, section, data, align) {} 110349cc55cSDimitry Andric 111fe6060f1SDimitry Andric uint64_t getOffset(uint64_t off) const override { return outSecOff + off; } 112fe6060f1SDimitry Andric uint64_t getVA() const { return InputSection::getVA(0); } 113fe6060f1SDimitry Andric // ConcatInputSections are entirely live or dead, so the offset is irrelevant. 114fe6060f1SDimitry Andric bool isLive(uint64_t off) const override { return live; } 115fe6060f1SDimitry Andric void markLive(uint64_t off) override { live = true; } 116349cc55cSDimitry Andric bool isCoalescedWeak() const { return wasCoalesced && symbols.empty(); } 117fe6060f1SDimitry Andric bool shouldOmitFromOutput() const { return !live || isCoalescedWeak(); } 118fe6060f1SDimitry Andric void writeTo(uint8_t *buf); 119fe6060f1SDimitry Andric 120fe6060f1SDimitry Andric void foldIdentical(ConcatInputSection *redundant); 121349cc55cSDimitry Andric ConcatInputSection *canonical() override { 122fe6060f1SDimitry Andric return replacement ? replacement : this; 123fe6060f1SDimitry Andric } 12404eeddc0SDimitry Andric const InputSection *canonical() const override { 12504eeddc0SDimitry Andric return replacement ? replacement : this; 12604eeddc0SDimitry Andric } 127fe6060f1SDimitry Andric 128fe6060f1SDimitry Andric static bool classof(const InputSection *isec) { 129fe6060f1SDimitry Andric return isec->kind() == ConcatKind; 130fe6060f1SDimitry Andric } 131fe6060f1SDimitry Andric 132fe6060f1SDimitry Andric // Points to the surviving section after this one is folded by ICF 133349cc55cSDimitry Andric ConcatInputSection *replacement = nullptr; 134fe6060f1SDimitry Andric // Equivalence-class ID for ICF 13581ad6265SDimitry Andric uint32_t icfEqClass[2] = {0, 0}; 136fe6060f1SDimitry Andric 137fe6060f1SDimitry Andric // With subsections_via_symbols, most symbols have their own InputSection, 138fe6060f1SDimitry Andric // and for weak symbols (e.g. from inline functions), only the 139fe6060f1SDimitry Andric // InputSection from one translation unit will make it to the output, 140fe6060f1SDimitry Andric // while all copies in other translation units are coalesced into the 141fe6060f1SDimitry Andric // first and not copied to the output. 142fe6060f1SDimitry Andric bool wasCoalesced = false; 143fe6060f1SDimitry Andric bool live = !config->deadStrip; 1440eae32dcSDimitry Andric bool hasCallSites = false; 145fe6060f1SDimitry Andric // This variable has two usages. Initially, it represents the input order. 146fe6060f1SDimitry Andric // After assignAddresses is called, it represents the offset from the 147fe6060f1SDimitry Andric // beginning of the output section this section was assigned to. 148fe6060f1SDimitry Andric uint64_t outSecOff = 0; 149fe6060f1SDimitry Andric }; 150fe6060f1SDimitry Andric 15181ad6265SDimitry Andric // Initialize a fake InputSection that does not belong to any InputFile. 15281ad6265SDimitry Andric ConcatInputSection *makeSyntheticInputSection(StringRef segName, 15381ad6265SDimitry Andric StringRef sectName, 15481ad6265SDimitry Andric uint32_t flags = 0, 15581ad6265SDimitry Andric ArrayRef<uint8_t> data = {}, 15681ad6265SDimitry Andric uint32_t align = 1); 15781ad6265SDimitry Andric 158fe6060f1SDimitry Andric // Helper functions to make it easy to sprinkle asserts. 159fe6060f1SDimitry Andric 160fe6060f1SDimitry Andric inline bool shouldOmitFromOutput(InputSection *isec) { 161fe6060f1SDimitry Andric return isa<ConcatInputSection>(isec) && 162fe6060f1SDimitry Andric cast<ConcatInputSection>(isec)->shouldOmitFromOutput(); 163fe6060f1SDimitry Andric } 164fe6060f1SDimitry Andric 165fe6060f1SDimitry Andric inline bool isCoalescedWeak(InputSection *isec) { 166fe6060f1SDimitry Andric return isa<ConcatInputSection>(isec) && 167fe6060f1SDimitry Andric cast<ConcatInputSection>(isec)->isCoalescedWeak(); 168fe6060f1SDimitry Andric } 169fe6060f1SDimitry Andric 170fe6060f1SDimitry Andric // We allocate a lot of these and binary search on them, so they should be as 171fe6060f1SDimitry Andric // compact as possible. Hence the use of 31 rather than 64 bits for the hash. 172fe6060f1SDimitry Andric struct StringPiece { 173fe6060f1SDimitry Andric // Offset from the start of the containing input section. 174fe6060f1SDimitry Andric uint32_t inSecOff; 175fe6060f1SDimitry Andric uint32_t live : 1; 176fe6060f1SDimitry Andric // Only set if deduplicating literals 177fe6060f1SDimitry Andric uint32_t hash : 31; 178fe6060f1SDimitry Andric // Offset from the start of the containing output section. 179fe6060f1SDimitry Andric uint64_t outSecOff = 0; 180fe6060f1SDimitry Andric 181fe6060f1SDimitry Andric StringPiece(uint64_t off, uint32_t hash) 182fe6060f1SDimitry Andric : inSecOff(off), live(!config->deadStrip), hash(hash) {} 183fe6060f1SDimitry Andric }; 184fe6060f1SDimitry Andric 185fe6060f1SDimitry Andric static_assert(sizeof(StringPiece) == 16, "StringPiece is too big!"); 186fe6060f1SDimitry Andric 187fe6060f1SDimitry Andric // CStringInputSections are composed of multiple null-terminated string 188fe6060f1SDimitry Andric // literals, which we represent using StringPieces. These literals can be 189fe6060f1SDimitry Andric // deduplicated and tail-merged, so translating offsets between the input and 190fe6060f1SDimitry Andric // outputs sections is more complicated. 191fe6060f1SDimitry Andric // 192fe6060f1SDimitry Andric // NOTE: One significant difference between LLD and ld64 is that we merge all 193fe6060f1SDimitry Andric // cstring literals, even those referenced directly by non-private symbols. 194fe6060f1SDimitry Andric // ld64 is more conservative and does not do that. This was mostly done for 195fe6060f1SDimitry Andric // implementation simplicity; if we find programs that need the more 196fe6060f1SDimitry Andric // conservative behavior we can certainly implement that. 197fe6060f1SDimitry Andric class CStringInputSection final : public InputSection { 198fe6060f1SDimitry Andric public: 19981ad6265SDimitry Andric CStringInputSection(const Section §ion, ArrayRef<uint8_t> data, 200bdd1243dSDimitry Andric uint32_t align, bool dedupLiterals) 201bdd1243dSDimitry Andric : InputSection(CStringLiteralKind, section, data, align), 202bdd1243dSDimitry Andric deduplicateLiterals(dedupLiterals) {} 203bdd1243dSDimitry Andric 204fe6060f1SDimitry Andric uint64_t getOffset(uint64_t off) const override; 205fe6060f1SDimitry Andric bool isLive(uint64_t off) const override { return getStringPiece(off).live; } 206fe6060f1SDimitry Andric void markLive(uint64_t off) override { getStringPiece(off).live = true; } 207fe6060f1SDimitry Andric // Find the StringPiece that contains this offset. 208fe6060f1SDimitry Andric StringPiece &getStringPiece(uint64_t off); 209fe6060f1SDimitry Andric const StringPiece &getStringPiece(uint64_t off) const; 210fe6060f1SDimitry Andric // Split at each null byte. 211fe6060f1SDimitry Andric void splitIntoPieces(); 212fe6060f1SDimitry Andric 213fe6060f1SDimitry Andric LLVM_ATTRIBUTE_ALWAYS_INLINE 214fe6060f1SDimitry Andric StringRef getStringRef(size_t i) const { 215fe6060f1SDimitry Andric size_t begin = pieces[i].inSecOff; 216bdd1243dSDimitry Andric // The endpoint should be *at* the null terminator, not after. This matches 217bdd1243dSDimitry Andric // the behavior of StringRef(const char *Str). 218fe6060f1SDimitry Andric size_t end = 219bdd1243dSDimitry Andric ((pieces.size() - 1 == i) ? data.size() : pieces[i + 1].inSecOff) - 1; 220fe6060f1SDimitry Andric return toStringRef(data.slice(begin, end - begin)); 221fe6060f1SDimitry Andric } 222fe6060f1SDimitry Andric 223*06c3fb27SDimitry Andric StringRef getStringRefAtOffset(uint64_t off) const { 224*06c3fb27SDimitry Andric return getStringRef(getStringPieceIndex(off)); 225*06c3fb27SDimitry Andric } 226*06c3fb27SDimitry Andric 227fe6060f1SDimitry Andric // Returns i'th piece as a CachedHashStringRef. This function is very hot when 228fe6060f1SDimitry Andric // string merging is enabled, so we want to inline. 229fe6060f1SDimitry Andric LLVM_ATTRIBUTE_ALWAYS_INLINE 230fe6060f1SDimitry Andric llvm::CachedHashStringRef getCachedHashStringRef(size_t i) const { 231bdd1243dSDimitry Andric assert(deduplicateLiterals); 232fe6060f1SDimitry Andric return {getStringRef(i), pieces[i].hash}; 233fe6060f1SDimitry Andric } 234fe6060f1SDimitry Andric 235fe6060f1SDimitry Andric static bool classof(const InputSection *isec) { 236fe6060f1SDimitry Andric return isec->kind() == CStringLiteralKind; 237fe6060f1SDimitry Andric } 238fe6060f1SDimitry Andric 239bdd1243dSDimitry Andric bool deduplicateLiterals = false; 240fe6060f1SDimitry Andric std::vector<StringPiece> pieces; 241*06c3fb27SDimitry Andric 242*06c3fb27SDimitry Andric private: 243*06c3fb27SDimitry Andric size_t getStringPieceIndex(uint64_t off) const; 244fe6060f1SDimitry Andric }; 245fe6060f1SDimitry Andric 246fe6060f1SDimitry Andric class WordLiteralInputSection final : public InputSection { 247fe6060f1SDimitry Andric public: 24881ad6265SDimitry Andric WordLiteralInputSection(const Section §ion, ArrayRef<uint8_t> data, 24981ad6265SDimitry Andric uint32_t align); 250fe6060f1SDimitry Andric uint64_t getOffset(uint64_t off) const override; 251fe6060f1SDimitry Andric bool isLive(uint64_t off) const override { 252fe6060f1SDimitry Andric return live[off >> power2LiteralSize]; 253fe6060f1SDimitry Andric } 25404eeddc0SDimitry Andric void markLive(uint64_t off) override { 25504eeddc0SDimitry Andric live[off >> power2LiteralSize] = true; 25604eeddc0SDimitry Andric } 257fe6060f1SDimitry Andric 258fe6060f1SDimitry Andric static bool classof(const InputSection *isec) { 259fe6060f1SDimitry Andric return isec->kind() == WordLiteralKind; 260fe6060f1SDimitry Andric } 261fe6060f1SDimitry Andric 262fe6060f1SDimitry Andric private: 263fe6060f1SDimitry Andric unsigned power2LiteralSize; 264fe6060f1SDimitry Andric // The liveness of data[off] is tracked by live[off >> power2LiteralSize]. 265fe6060f1SDimitry Andric llvm::BitVector live; 2665ffd83dbSDimitry Andric }; 2675ffd83dbSDimitry Andric 268e8d8bef9SDimitry Andric inline uint8_t sectionType(uint32_t flags) { 269e8d8bef9SDimitry Andric return flags & llvm::MachO::SECTION_TYPE; 270e8d8bef9SDimitry Andric } 271e8d8bef9SDimitry Andric 272e8d8bef9SDimitry Andric inline bool isZeroFill(uint32_t flags) { 273e8d8bef9SDimitry Andric return llvm::MachO::isVirtualSection(sectionType(flags)); 274e8d8bef9SDimitry Andric } 275e8d8bef9SDimitry Andric 276e8d8bef9SDimitry Andric inline bool isThreadLocalVariables(uint32_t flags) { 277e8d8bef9SDimitry Andric return sectionType(flags) == llvm::MachO::S_THREAD_LOCAL_VARIABLES; 278e8d8bef9SDimitry Andric } 279e8d8bef9SDimitry Andric 280e8d8bef9SDimitry Andric // These sections contain the data for initializing thread-local variables. 281e8d8bef9SDimitry Andric inline bool isThreadLocalData(uint32_t flags) { 282e8d8bef9SDimitry Andric return sectionType(flags) == llvm::MachO::S_THREAD_LOCAL_REGULAR || 283e8d8bef9SDimitry Andric sectionType(flags) == llvm::MachO::S_THREAD_LOCAL_ZEROFILL; 284e8d8bef9SDimitry Andric } 285e8d8bef9SDimitry Andric 286e8d8bef9SDimitry Andric inline bool isDebugSection(uint32_t flags) { 287e8d8bef9SDimitry Andric return (flags & llvm::MachO::SECTION_ATTRIBUTES_USR) == 288e8d8bef9SDimitry Andric llvm::MachO::S_ATTR_DEBUG; 289e8d8bef9SDimitry Andric } 290e8d8bef9SDimitry Andric 291fe6060f1SDimitry Andric inline bool isWordLiteralSection(uint32_t flags) { 292fe6060f1SDimitry Andric return sectionType(flags) == llvm::MachO::S_4BYTE_LITERALS || 293fe6060f1SDimitry Andric sectionType(flags) == llvm::MachO::S_8BYTE_LITERALS || 294fe6060f1SDimitry Andric sectionType(flags) == llvm::MachO::S_16BYTE_LITERALS; 295fe6060f1SDimitry Andric } 296e8d8bef9SDimitry Andric 297fe6060f1SDimitry Andric bool isCodeSection(const InputSection *); 298fe6060f1SDimitry Andric bool isCfStringSection(const InputSection *); 29981ad6265SDimitry Andric bool isClassRefsSection(const InputSection *); 300bdd1243dSDimitry Andric bool isSelRefsSection(const InputSection *); 30181ad6265SDimitry Andric bool isEhFrameSection(const InputSection *); 302fcaf7f86SDimitry Andric bool isGccExceptTabSection(const InputSection *); 303fe6060f1SDimitry Andric 304fe6060f1SDimitry Andric extern std::vector<ConcatInputSection *> inputSections; 305fe6060f1SDimitry Andric 306fe6060f1SDimitry Andric namespace section_names { 307fe6060f1SDimitry Andric 308fe6060f1SDimitry Andric constexpr const char authGot[] = "__auth_got"; 309fe6060f1SDimitry Andric constexpr const char authPtr[] = "__auth_ptr"; 310fe6060f1SDimitry Andric constexpr const char binding[] = "__binding"; 311fe6060f1SDimitry Andric constexpr const char bitcodeBundle[] = "__bundle"; 312fe6060f1SDimitry Andric constexpr const char cString[] = "__cstring"; 313fe6060f1SDimitry Andric constexpr const char cfString[] = "__cfstring"; 31481ad6265SDimitry Andric constexpr const char cgProfile[] = "__cg_profile"; 315bdd1243dSDimitry Andric constexpr const char chainFixups[] = "__chainfixups"; 316fe6060f1SDimitry Andric constexpr const char codeSignature[] = "__code_signature"; 317fe6060f1SDimitry Andric constexpr const char common[] = "__common"; 318fe6060f1SDimitry Andric constexpr const char compactUnwind[] = "__compact_unwind"; 319fe6060f1SDimitry Andric constexpr const char data[] = "__data"; 320fe6060f1SDimitry Andric constexpr const char debugAbbrev[] = "__debug_abbrev"; 321fe6060f1SDimitry Andric constexpr const char debugInfo[] = "__debug_info"; 32281ad6265SDimitry Andric constexpr const char debugLine[] = "__debug_line"; 323fe6060f1SDimitry Andric constexpr const char debugStr[] = "__debug_str"; 324bdd1243dSDimitry Andric constexpr const char debugStrOffs[] = "__debug_str_offs"; 325fe6060f1SDimitry Andric constexpr const char ehFrame[] = "__eh_frame"; 326349cc55cSDimitry Andric constexpr const char gccExceptTab[] = "__gcc_except_tab"; 327fe6060f1SDimitry Andric constexpr const char export_[] = "__export"; 328fe6060f1SDimitry Andric constexpr const char dataInCode[] = "__data_in_code"; 329fe6060f1SDimitry Andric constexpr const char functionStarts[] = "__func_starts"; 330fe6060f1SDimitry Andric constexpr const char got[] = "__got"; 331fe6060f1SDimitry Andric constexpr const char header[] = "__mach_header"; 332fe6060f1SDimitry Andric constexpr const char indirectSymbolTable[] = "__ind_sym_tab"; 333bdd1243dSDimitry Andric constexpr const char initOffsets[] = "__init_offsets"; 334fe6060f1SDimitry Andric constexpr const char const_[] = "__const"; 335fe6060f1SDimitry Andric constexpr const char lazySymbolPtr[] = "__la_symbol_ptr"; 336fe6060f1SDimitry Andric constexpr const char lazyBinding[] = "__lazy_binding"; 337fe6060f1SDimitry Andric constexpr const char literals[] = "__literals"; 338fe6060f1SDimitry Andric constexpr const char moduleInitFunc[] = "__mod_init_func"; 339fe6060f1SDimitry Andric constexpr const char moduleTermFunc[] = "__mod_term_func"; 340fe6060f1SDimitry Andric constexpr const char nonLazySymbolPtr[] = "__nl_symbol_ptr"; 341fe6060f1SDimitry Andric constexpr const char objcCatList[] = "__objc_catlist"; 342fe6060f1SDimitry Andric constexpr const char objcClassList[] = "__objc_classlist"; 34381ad6265SDimitry Andric constexpr const char objcClassRefs[] = "__objc_classrefs"; 344fe6060f1SDimitry Andric constexpr const char objcConst[] = "__objc_const"; 345fcaf7f86SDimitry Andric constexpr const char objCImageInfo[] = "__objc_imageinfo"; 346bdd1243dSDimitry Andric constexpr const char objcStubs[] = "__objc_stubs"; 347bdd1243dSDimitry Andric constexpr const char objcSelrefs[] = "__objc_selrefs"; 348bdd1243dSDimitry Andric constexpr const char objcMethname[] = "__objc_methname"; 349fe6060f1SDimitry Andric constexpr const char objcNonLazyCatList[] = "__objc_nlcatlist"; 350fe6060f1SDimitry Andric constexpr const char objcNonLazyClassList[] = "__objc_nlclslist"; 351fe6060f1SDimitry Andric constexpr const char objcProtoList[] = "__objc_protolist"; 352fe6060f1SDimitry Andric constexpr const char pageZero[] = "__pagezero"; 353fe6060f1SDimitry Andric constexpr const char pointers[] = "__pointers"; 354fe6060f1SDimitry Andric constexpr const char rebase[] = "__rebase"; 355fe6060f1SDimitry Andric constexpr const char staticInit[] = "__StaticInit"; 356fe6060f1SDimitry Andric constexpr const char stringTable[] = "__string_table"; 357fe6060f1SDimitry Andric constexpr const char stubHelper[] = "__stub_helper"; 358fe6060f1SDimitry Andric constexpr const char stubs[] = "__stubs"; 359fe6060f1SDimitry Andric constexpr const char swift[] = "__swift"; 360fe6060f1SDimitry Andric constexpr const char symbolTable[] = "__symbol_table"; 361fe6060f1SDimitry Andric constexpr const char textCoalNt[] = "__textcoal_nt"; 362fe6060f1SDimitry Andric constexpr const char text[] = "__text"; 363fe6060f1SDimitry Andric constexpr const char threadPtrs[] = "__thread_ptrs"; 364fe6060f1SDimitry Andric constexpr const char threadVars[] = "__thread_vars"; 365fe6060f1SDimitry Andric constexpr const char unwindInfo[] = "__unwind_info"; 366fe6060f1SDimitry Andric constexpr const char weakBinding[] = "__weak_binding"; 367fe6060f1SDimitry Andric constexpr const char zeroFill[] = "__zerofill"; 36881ad6265SDimitry Andric constexpr const char addrSig[] = "__llvm_addrsig"; 369fe6060f1SDimitry Andric 370fe6060f1SDimitry Andric } // namespace section_names 3715ffd83dbSDimitry Andric 3725ffd83dbSDimitry Andric } // namespace macho 373e8d8bef9SDimitry Andric 374e8d8bef9SDimitry Andric std::string toString(const macho::InputSection *); 375e8d8bef9SDimitry Andric 3765ffd83dbSDimitry Andric } // namespace lld 3775ffd83dbSDimitry Andric 3785ffd83dbSDimitry Andric #endif 379