Index: ELF/Writer.cpp =================================================================== --- ELF/Writer.cpp +++ ELF/Writer.cpp @@ -1701,17 +1701,29 @@ // The linker is expected to define SECNAME_start and SECNAME_end // symbols for a few sections. This function defines them. template void Writer::addStartEndSymbols() { - auto Define = [&](StringRef Start, StringRef End, OutputSection *OS) { - // These symbols resolve to the image base if the section does not exist. - // A special value -1 indicates end of the section. + // If a section does not exist, there's ambiguity as to how we + // define _start and _end symbols for an init/fini section. Since + // the loader assume that the symbols are always defined, we need to + // always define them. But what value? The loader iterates over all + // pointers between _start and _end to run global ctors/dtors, so if + // the section is empty, their symbol values don't actually matter + // as long as _start and _end point to the same location. + + // That said, we don't want to set the symbols to 0 (which is + // probably the simplest value) because that could cause some + // program to fail to link due to relocation overflow, if their + // program text is above 2 GiB. We use the address of the .text + // section instead to prevent that failure. + OutputSection *Default = findSection(".text"); + if (!Default) + Default = Out::ElfHeader; + auto Define = [=](StringRef Start, StringRef End, OutputSection *OS) { if (OS) { addOptionalRegular(Start, OS, 0); addOptionalRegular(End, OS, -1); } else { - if (Config->Pic) - OS = Out::ElfHeader; - addOptionalRegular(Start, OS, 0); - addOptionalRegular(End, OS, 0); + addOptionalRegular(Start, Default, 0); + addOptionalRegular(End, Default, 0); } }; Index: test/ELF/pre_init_fini_array_missing.s =================================================================== --- test/ELF/pre_init_fini_array_missing.s +++ test/ELF/pre_init_fini_array_missing.s @@ -14,30 +14,27 @@ call __fini_array_start call __fini_array_end -// With no .init_array section the symbols resolve to 0 -// 0 - (0x201000 + 5) = -2101253 -// 0 - (0x201005 + 5) = -2101258 -// 0 - (0x20100a + 5) = -2101263 -// 0 - (0x20100f + 5) = -2101268 -// 0 - (0x201014 + 5) = -2101273 -// 0 - (0x201019 + 5) = -2101278 +// With no .init_array section the symbols resolve to .text. +// 0x201000 - (0x201000 + 5) = -5 +// 0x201000 - (0x201005 + 5) = -10 +// ... // CHECK: Disassembly of section .text: // CHECK-NEXT: _start: -// CHECK-NEXT: 201000: e8 fb ef df ff callq -2101253 -// CHECK-NEXT: 201005: e8 f6 ef df ff callq -2101258 -// CHECK-NEXT: 20100a: e8 f1 ef df ff callq -2101263 -// CHECK-NEXT: 20100f: e8 ec ef df ff callq -2101268 -// CHECK-NEXT: 201014: e8 e7 ef df ff callq -2101273 -// CHECK-NEXT: 201019: e8 e2 ef df ff callq -2101278 +// CHECK-NEXT: 201000: e8 fb ff ff ff callq -5 +// CHECK-NEXT: 201005: e8 f6 ff ff ff callq -10 +// CHECK-NEXT: 20100a: e8 f1 ff ff ff callq -15 +// CHECK-NEXT: 20100f: e8 ec ff ff ff callq -20 +// CHECK-NEXT: 201014: e8 e7 ff ff ff callq -25 +// CHECK-NEXT: 201019: e8 e2 ff ff ff callq -30 -// In position-independent binaries, they resolve to the image base. +// In position-independent binaries, they resolve to .text too. // PIE: Disassembly of section .text: // PIE-NEXT: _start: -// PIE-NEXT: 1000: e8 fb ef ff ff callq -4101 -// PIE-NEXT: 1005: e8 f6 ef ff ff callq -4106 -// PIE-NEXT: 100a: e8 f1 ef ff ff callq -4111 -// PIE-NEXT: 100f: e8 ec ef ff ff callq -4116 -// PIE-NEXT: 1014: e8 e7 ef ff ff callq -4121 -// PIE-NEXT: 1019: e8 e2 ef ff ff callq -4126 +// PIE-NEXT: 1000: e8 fb ff ff ff callq -5 +// PIE-NEXT: 1005: e8 f6 ff ff ff callq -10 +// PIE-NEXT: 100a: e8 f1 ff ff ff callq -15 +// PIE-NEXT: 100f: e8 ec ff ff ff callq -20 +// PIE-NEXT: 1014: e8 e7 ff ff ff callq -25 +// PIE-NEXT: 1019: e8 e2 ff ff ff callq -30