diff --git a/lld/MachO/SyntheticSections.h b/lld/MachO/SyntheticSections.h --- a/lld/MachO/SyntheticSections.h +++ b/lld/MachO/SyntheticSections.h @@ -46,6 +46,12 @@ // these are not synthetic, but in service of synthetic __unwind_info constexpr const char compactUnwind[] = "__compact_unwind"; constexpr const char ehFrame[] = "__eh_frame"; +// these are not synthetic, but need to be sorted +constexpr const char text[] = "__text"; +constexpr const char stubs[] = "__stubs"; +constexpr const char stubHelper[] = "__stub_helper"; +constexpr const char laSymbolPtr[] = "__la_symbol_ptr"; +constexpr const char data[] = "__data"; } // namespace section_names diff --git a/lld/MachO/SyntheticSections.cpp b/lld/MachO/SyntheticSections.cpp --- a/lld/MachO/SyntheticSections.cpp +++ b/lld/MachO/SyntheticSections.cpp @@ -188,7 +188,7 @@ NonLazyPointerSectionBase::NonLazyPointerSectionBase(const char *segname, const char *name) : SyntheticSection(segname, name) { - align = 8; + align = WordSize; flags = MachO::S_NON_LAZY_SYMBOL_POINTERS; } @@ -391,7 +391,9 @@ StubsSection::StubsSection() : SyntheticSection(segment_names::text, "__stubs") { - flags = MachO::S_SYMBOL_STUBS; + flags = MachO::S_SYMBOL_STUBS | MachO::S_ATTR_SOME_INSTRUCTIONS | + MachO::S_ATTR_PURE_INSTRUCTIONS; + align = 4; reserved2 = target->stubSize; } @@ -415,7 +417,10 @@ } StubHelperSection::StubHelperSection() - : SyntheticSection(segment_names::text, "__stub_helper") {} + : SyntheticSection(segment_names::text, "__stub_helper") { + flags = MachO::S_ATTR_SOME_INSTRUCTIONS | MachO::S_ATTR_PURE_INSTRUCTIONS; + align = 4; +} uint64_t StubHelperSection::getSize() const { return target->stubHelperHeaderSize + @@ -456,11 +461,12 @@ uint8_t *arr = bAlloc.Allocate(WordSize); memset(arr, 0, WordSize); data = {arr, WordSize}; + align = WordSize; } LazyPointerSection::LazyPointerSection() : SyntheticSection(segment_names::data, "__la_symbol_ptr") { - align = 8; + align = WordSize; flags = MachO::S_LAZY_SYMBOL_POINTERS; } diff --git a/lld/MachO/Target.h b/lld/MachO/Target.h --- a/lld/MachO/Target.h +++ b/lld/MachO/Target.h @@ -27,7 +27,7 @@ // We are currently only supporting 64-bit targets since macOS and iOS are // deprecating 32-bit apps. WordSize = 8, - PageSize = 4096, + PageSize = 0x4000, // 16 KiB PageZeroSize = 1ull << 32, // XXX should be 4096 for 32-bit targets MaxAlignmentPowerOf2 = 32, }; diff --git a/lld/MachO/UnwindInfoSection.cpp b/lld/MachO/UnwindInfoSection.cpp --- a/lld/MachO/UnwindInfoSection.cpp +++ b/lld/MachO/UnwindInfoSection.cpp @@ -87,7 +87,7 @@ UnwindInfoSection::UnwindInfoSection() : SyntheticSection(segment_names::text, section_names::unwindInfo) { - align = WordSize; // TODO(gkm): make this 4 KiB ? + align = 4; } bool UnwindInfoSection::isNeeded() const { diff --git a/lld/MachO/Writer.cpp b/lld/MachO/Writer.cpp --- a/lld/MachO/Writer.cpp +++ b/lld/MachO/Writer.cpp @@ -437,6 +437,12 @@ } void Writer::createLoadCommands() { + uint8_t segIndex = 0; + for (OutputSegment *seg : outputSegments) { + in.header->addLoadCommand(make(seg->name, seg)); + seg->index = segIndex++; + } + in.header->addLoadCommand(make( in.rebase, in.binding, in.weakBinding, in.lazyBinding, in.exports)); in.header->addLoadCommand(make(symtabSection, stringTableSection)); @@ -447,8 +453,8 @@ switch (config->outputType) { case MH_EXECUTE: - in.header->addLoadCommand(make()); in.header->addLoadCommand(make()); + in.header->addLoadCommand(make()); break; case MH_DYLIB: in.header->addLoadCommand(make(LC_ID_DYLIB, config->installName, @@ -461,16 +467,10 @@ llvm_unreachable("unhandled output file type"); } - in.header->addLoadCommand(make(config->platform)); - uuidCommand = make(); in.header->addLoadCommand(uuidCommand); - uint8_t segIndex = 0; - for (OutputSegment *seg : outputSegments) { - in.header->addLoadCommand(make(seg->name, seg)); - seg->index = segIndex++; - } + in.header->addLoadCommand(make(config->platform)); uint64_t dylibOrdinal = 1; for (InputFile *file : inputFiles) { @@ -540,8 +540,10 @@ static int segmentOrder(OutputSegment *seg) { return StringSwitch(seg->name) - .Case(segment_names::pageZero, -2) - .Case(segment_names::text, -1) + .Case(segment_names::pageZero, -4) + .Case(segment_names::text, -3) + .Case(segment_names::dataConst, -2) + .Case(segment_names::data, -1) // Make sure __LINKEDIT is the last segment (i.e. all its hidden // sections must be ordered after other sections). .Case(segment_names::linkEdit, std::numeric_limits::max()) @@ -553,12 +555,14 @@ // Sections are uniquely identified by their segment + section name. if (segname == segment_names::text) { return StringSwitch(osec->name) - .Case(section_names::header, -1) + .Case(section_names::header, -4) + .Case(section_names::text, -3) + .Case(section_names::stubs, -2) + .Case(section_names::stubHelper, -1) .Case(section_names::unwindInfo, std::numeric_limits::max() - 1) .Case(section_names::ehFrame, std::numeric_limits::max()) .Default(0); - } - if (segname == segment_names::data) { + } else if (segname == segment_names::data) { // For each thread spawned, dyld will initialize its TLVs by copying the // address range from the start of the first thread-local data section to // the end of the last one. We therefore arrange these sections contiguously @@ -574,10 +578,12 @@ case S_ZEROFILL: return std::numeric_limits::max(); default: - return 0; + return StringSwitch(osec->name) + .Case(section_names::laSymbolPtr, -2) + .Case(section_names::data, -1) + .Default(0); } - } - if (segname == segment_names::linkEdit) { + } else if (segname == segment_names::linkEdit) { return StringSwitch(osec->name) .Case(section_names::rebase, -8) .Case(section_names::binding, -7) diff --git a/lld/test/MachO/bss.s b/lld/test/MachO/bss.s --- a/lld/test/MachO/bss.s +++ b/lld/test/MachO/bss.s @@ -14,7 +14,7 @@ # CHECK-NEXT: Segment: __DATA # CHECK-NEXT: Address: # CHECK-NEXT: Size: 0x8 -# CHECK-NEXT: Offset: 4096 +# CHECK-NEXT: Offset: 16384 # CHECK-NEXT: Alignment: 0 # CHECK-NEXT: RelocationOffset: 0x0 # CHECK-NEXT: RelocationCount: 0 @@ -62,7 +62,7 @@ # CHECK-NEXT: Segment: FOO # CHECK-NEXT: Address: # CHECK-NEXT: Size: 0x8 -# CHECK-NEXT: Offset: 8192 +# CHECK-NEXT: Offset: 32768 # CHECK-NEXT: Alignment: 0 # CHECK-NEXT: RelocationOffset: 0x0 # CHECK-NEXT: RelocationCount: 0 diff --git a/lld/test/MachO/dylib-stub.yaml b/lld/test/MachO/dylib-stub.yaml --- a/lld/test/MachO/dylib-stub.yaml +++ b/lld/test/MachO/dylib-stub.yaml @@ -14,7 +14,7 @@ # RUN: yaml2obj %t/fat.dylib.yaml > %t/fat.dylib # RUN: %lld -lSystem %t/test.o %t/fat.dylib -o %t/test # RUN: llvm-objdump --macho --lazy-bind %t/test | FileCheck %s -# CHECK: __DATA __la_symbol_ptr 0x100001008 foo _foo +# CHECK: __DATA __la_symbol_ptr 0x100008000 foo _foo #--- test.s .globl _main diff --git a/lld/test/MachO/entry-symbol.s b/lld/test/MachO/entry-symbol.s --- a/lld/test/MachO/entry-symbol.s +++ b/lld/test/MachO/entry-symbol.s @@ -8,16 +8,16 @@ # RUN: llvm-objdump --macho --all-headers --syms %t/not-main | FileCheck %s # CHECK-LABEL: SYMBOL TABLE # CHECK-NEXT: {{0*}}[[#%x, ENTRY_ADDR:]] {{.*}} __TEXT,__text _not_main -# CHECK: cmd LC_MAIN -# CHECK-NEXT: cmdsize 24 -# CHECK-NEXT: entryoff [[#ENTRYOFF:]] # CHECK: sectname __text # CHECK-NEXT: segname __TEXT ## Note: the following checks assume that the entry symbol is right at the ## beginning of __text. # CHECK-NEXT: addr 0x{{0*}}[[#ENTRY_ADDR]] # CHECK-NEXT: size -# CHECK-NEXT: offset [[#ENTRYOFF]] +# CHECK-NEXT: offset [[#ENTRYOFF:]] +# CHECK: cmd LC_MAIN +# CHECK-NEXT: cmdsize 24 +# CHECK-NEXT: entryoff [[#ENTRYOFF]] # RUN: %lld -lSystem -o %t/dysym-main %t/not-main.o %t/libfoo.dylib -e _dysym_main # RUN: llvm-objdump --macho --all-headers --indirect-symbols --lazy-bind %t/dysym-main | FileCheck %s --check-prefix=DYSYM diff --git a/lld/test/MachO/indirect-symtab.s b/lld/test/MachO/indirect-symtab.s --- a/lld/test/MachO/indirect-symtab.s +++ b/lld/test/MachO/indirect-symtab.s @@ -20,19 +20,19 @@ # CHECK-NEXT: address index name # CHECK-NEXT: _bar_fn # CHECK-NEXT: _foo_fn -# CHECK-NEXT: Indirect symbols for (__DATA,__thread_ptrs) 2 entries +# CHECK-NEXT: Indirect symbols for (__DATA_CONST,__got) 3 entries # CHECK-NEXT: address index name -# CHECK-NEXT: _bar_tlv -# CHECK-NEXT: _foo_tlv +# CHECK-NEXT: _bar +# CHECK-NEXT: _foo +# CHECK-NEXT: _stub_binder # CHECK-NEXT: Indirect symbols for (__DATA,__la_symbol_ptr) 2 entries # CHECK-NEXT: address index name # CHECK-NEXT: _bar_fn # CHECK-NEXT: _foo_fn -# CHECK-NEXT: Indirect symbols for (__DATA_CONST,__got) 3 entries +# CHECK-NEXT: Indirect symbols for (__DATA,__thread_ptrs) 2 entries # CHECK-NEXT: address index name -# CHECK-NEXT: _bar -# CHECK-NEXT: _foo -# CHECK-NEXT: _stub_binder +# CHECK-NEXT: _bar_tlv +# CHECK-NEXT: _foo_tlv #--- libfoo.s diff --git a/lld/test/MachO/lc-build-version.s b/lld/test/MachO/lc-build-version.s --- a/lld/test/MachO/lc-build-version.s +++ b/lld/test/MachO/lc-build-version.s @@ -11,7 +11,6 @@ # CHECK-NEXT: ntools 1 # CHECK-NEXT: tool ld # CHECK-NEXT: version {{[0-9\.]+}} -# CHECK-NEXT: Load command [[#]] .text .global _main diff --git a/lld/test/MachO/relocations.s b/lld/test/MachO/relocations.s --- a/lld/test/MachO/relocations.s +++ b/lld/test/MachO/relocations.s @@ -21,7 +21,7 @@ # RUN: llvm-objdump --section=__const --full-contents %t | FileCheck %s --check-prefix=NONPCREL # NONPCREL: Contents of section __DATA,__const: -# NONPCREL-NEXT: 100001000 08040000 01000000 08040000 01000000 +# NONPCREL-NEXT: 100004000 08040000 01000000 08040000 01000000 .section __TEXT,__text .globl _main, _f diff --git a/lld/test/MachO/symtab.s b/lld/test/MachO/symtab.s --- a/lld/test/MachO/symtab.s +++ b/lld/test/MachO/symtab.s @@ -10,7 +10,7 @@ # CHECK-NEXT: Symbol { # CHECK-NEXT: Name: _local # CHECK-NEXT: Type: Section (0xE) -# CHECK-NEXT: Section: __data (0x4) +# CHECK-NEXT: Section: __data (0x{{[0-9a-f]}}) # CHECK-NEXT: RefType: UndefinedNonLazy (0x0) # CHECK-NEXT: Flags [ (0x0) # CHECK-NEXT: ] @@ -19,7 +19,7 @@ # CHECK-NEXT: Symbol { # CHECK-NEXT: Name: __dyld_private # CHECK-NEXT: Type: Section (0xE) -# CHECK-NEXT: Section: __data (0x4) +# CHECK-NEXT: Section: __data (0x{{[0-9a-f]}}) # CHECK-NEXT: RefType: UndefinedNonLazy (0x0) # CHECK-NEXT: Flags [ (0x0) # CHECK-NEXT: ] @@ -39,7 +39,7 @@ # CHECK-NEXT: Name: _external # CHECK-NEXT: Extern # CHECK-NEXT: Type: Section (0xE) -# CHECK-NEXT: Section: __data (0x4) +# CHECK-NEXT: Section: __data (0x{{[0-9a-f]}}) # CHECK-NEXT: RefType: UndefinedNonLazy (0x0) # CHECK-NEXT: Flags [ (0x0) # CHECK-NEXT: ] diff --git a/lld/test/MachO/weak-binding.s b/lld/test/MachO/weak-binding.s --- a/lld/test/MachO/weak-binding.s +++ b/lld/test/MachO/weak-binding.s @@ -7,15 +7,15 @@ # RUN: llvm-objdump -d --no-show-raw-insn --bind --lazy-bind --weak-bind --full-contents %t/test | \ # RUN: FileCheck %s -# CHECK: Contents of section __DATA,__la_symbol_ptr: +# CHECK: Contents of section __DATA_CONST,__got: ## Check that this section contains a nonzero pointer. It should point to -## _weak_external_fn, but we don't have a good way of testing the exact value as -## the bytes here are in little-endian order. +## _weak_external_for_gotpcrel. # CHECK-NEXT: {{[0-9a-f]+}} {{[0-9a-f ]*[1-9a-f]+[0-9a-f ]*}} -# CHECK: Contents of section __DATA_CONST,__got: +# CHECK: Contents of section __DATA,__la_symbol_ptr: ## Check that this section contains a nonzero pointer. It should point to -## _weak_external_for_gotpcrel. +## _weak_external_fn, but we don't have a good way of testing the exact value as +## the bytes here are in little-endian order. # CHECK-NEXT: {{[0-9a-f]+}} {{[0-9a-f ]*[1-9a-f]+[0-9a-f ]*}} # CHECK: <_main>: @@ -30,11 +30,11 @@ # CHECK-NEXT: callq 0x{{[0-9a-f]*}} # CHECK-LABEL: Bind table: +# CHECK-DAG: __DATA_CONST __got 0x[[#WEAK_DY_GOT_ADDR]] pointer 0 libfoo _weak_dysym_for_gotpcrel +# CHECK-DAG: __DATA __la_symbol_ptr 0x[[#%x,WEAK_DY_FN:]] pointer 0 libfoo _weak_dysym_fn # CHECK-DAG: __DATA __data 0x[[#%x,WEAK_DY:]] pointer 0 libfoo _weak_dysym # CHECK-DAG: __DATA __thread_vars 0x{{[0-9a-f]*}} pointer 0 libSystem __tlv_bootstrap # CHECK-DAG: __DATA __thread_ptrs 0x[[#WEAK_DY_TLV_ADDR]] pointer 0 libfoo _weak_dysym_tlv -# CHECK-DAG: __DATA_CONST __got 0x[[#WEAK_DY_GOT_ADDR]] pointer 0 libfoo _weak_dysym_for_gotpcrel -# CHECK-DAG: __DATA __la_symbol_ptr 0x[[#%x,WEAK_DY_FN:]] pointer 0 libfoo _weak_dysym_fn ## Check that we don't have any other bindings # CHECK-NOT: pointer diff --git a/lld/test/MachO/weak-reference.s b/lld/test/MachO/weak-reference.s --- a/lld/test/MachO/weak-reference.s +++ b/lld/test/MachO/weak-reference.s @@ -34,10 +34,10 @@ # YAML-LABEL: WeakBindOpcodes: # YAML: - Opcode: BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM # YAML-NEXT: Imm: 0 -# YAML-NEXT: Symbol: _weak_foo +# YAML-NEXT: Symbol: _weak_foo_fn # YAML: - Opcode: BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM # YAML-NEXT: Imm: 0 -# YAML-NEXT: Symbol: _weak_foo_fn +# YAML-NEXT: Symbol: _weak_foo # YAML-LABEL: LazyBindOpcodes: # YAML: - Opcode: BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM # YAML-NEXT: Imm: 1 @@ -79,13 +79,10 @@ # STRONG-YAML-LABEL: WeakBindOpcodes: # STRONG-YAML: - Opcode: BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM # STRONG-YAML-NEXT: Imm: 0 -# STRONG-YAML-NEXT: Symbol: _weak_foo +# STRONG-YAML-NEXT: Symbol: _weak_foo_fn # STRONG-YAML: - Opcode: BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM # STRONG-YAML-NEXT: Imm: 0 # STRONG-YAML-NEXT: Symbol: _weak_foo -# STRONG-YAML: - Opcode: BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM -# STRONG-YAML-NEXT: Imm: 0 -# STRONG-YAML-NEXT: Symbol: _weak_foo_fn # STRONG-YAML-LABEL: LazyBindOpcodes: # STRONG-YAML: - Opcode: BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM # STRONG-YAML-NEXT: Imm: 0 diff --git a/lld/test/MachO/x86-64-reloc-signed.s b/lld/test/MachO/x86-64-reloc-signed.s --- a/lld/test/MachO/x86-64-reloc-signed.s +++ b/lld/test/MachO/x86-64-reloc-signed.s @@ -4,18 +4,18 @@ # RUN: llvm-objdump -D %t | FileCheck %s # CHECK: <_main>: -# CHECK-NEXT: movl {{.*}} # 100001000 <_s> +# CHECK-NEXT: movl {{.*}} # 100004000 <_s> # CHECK-NEXT: callq {{.*}} -# CHECK-NEXT: movl {{.*}} # 100001002 <_s+0x2> +# CHECK-NEXT: movl {{.*}} # 100004002 <_s+0x2> # CHECK-NEXT: callq {{.*}} -# CHECK-NEXT: movb {{.*}} # 100001000 <_s> +# CHECK-NEXT: movb {{.*}} # 100004000 <_s> # CHECK-NEXT: callq {{.*}} # CHECK: <__not_text>: -# CHECK-NEXT: movl {{.*}} # 100001005 +# CHECK-NEXT: movl {{.*}} # 100004005 # CHECK-NEXT: callq {{.*}} -# CHECK-NEXT: movl {{.*}} # 100001007 +# CHECK-NEXT: movl {{.*}} # 100004007 # CHECK-NEXT: callq {{.*}} -# CHECK-NEXT: movb {{.*}} # 100001005 +# CHECK-NEXT: movb {{.*}} # 100004005 # CHECK-NEXT: callq {{.*}} .section __TEXT,__text diff --git a/lld/test/MachO/x86-64-reloc-unsigned.s b/lld/test/MachO/x86-64-reloc-unsigned.s --- a/lld/test/MachO/x86-64-reloc-unsigned.s +++ b/lld/test/MachO/x86-64-reloc-unsigned.s @@ -20,9 +20,9 @@ # RUN: llvm-objdump --macho --rebase %t-pie | FileCheck %s --check-prefix=PIE # CHECK: Contents of section __DATA,foo: -# CHECK-NEXT: 100001000 08100000 01000000 +# CHECK-NEXT: 100004000 08400000 01000000 # CHECK: Contents of section __DATA,bar: -# CHECK-NEXT: 100001008 011000f0 11211111 02000000 +# CHECK-NEXT: 100004008 014000f0 11511111 02000000 # CHECK: Rebase table: # CHECK-NEXT: segment section address type # CHECK-EMPTY: