The first PT_LOAD segment is traditionally mapped with R+X permission and contains the .text section. rtld assumes this is the case and the temporarily maps this segment RWX while applying non-plt relocations. The LLVM linker lld currently puts .rodata in the first PT_LOAD with only R permission and .text in the second PT_LOAD with RX. rtld then segfaults while trying to apply relocations to .text which has not been updated with write permission.
For reference here is the segment layout currently produced by lld: % readelf -l bin/sh Elf file type is EXEC (Executable file) Entry point 0x19000 There are 10 program headers, starting at offset 64 Program Headers: Type Offset VirtAddr PhysAddr FileSiz MemSiz Flags Align PHDR 0x0000000000000040 0x0000000000010040 0x0000000000010040 0x0000000000000230 0x0000000000000230 R 8 INTERP 0x0000000000000270 0x0000000000010270 0x0000000000010270 0x0000000000000015 0x0000000000000015 R 1 [Requesting program interpreter: /libexec/ld-elf.so.1] LOAD 0x0000000000000000 0x0000000000010000 0x0000000000010000 0x000000000000875c 0x000000000000875c R 1000 LOAD 0x0000000000009000 0x0000000000019000 0x0000000000019000 0x000000000001b220 0x000000000001b220 R E 1000 LOAD 0x0000000000025000 0x0000000000035000 0x0000000000035000 0x0000000000001500 0x0000000000003a50 RW 1000 DYNAMIC 0x0000000000025028 0x0000000000035028 0x0000000000035028 0x0000000000000130 0x0000000000000130 RW 8 GNU_RELRO 0x0000000000025000 0x0000000000035000 0x0000000000035000 0x0000000000000160 0x0000000000000160 R 1 GNU_EH_FRAME 0x0000000000007f18 0x0000000000017f18 0x0000000000017f18 0x0000000000000844 0x0000000000000844 R 1 GNU_STACK 0x0000000000000000 0x0000000000000000 0x0000000000000000 0x0000000000000000 0x0000000000000000 RW 0 NOTE 0x0000000000000288 0x0000000000010288 0x0000000000010288 0x0000000000000030 0x0000000000000030 R 4 Section to Segment mapping: Segment Sections... 00 01 .interp 02 .interp .note.tag .rodata .eh_frame .rodata .rodata .rodata .dynsym .gnu.hash .hash .dynstr .rela.dyn .rela.plt .eh_frame_hdr 03 .text .init .fini .plt 04 .ctors .dtors .jcr .dynamic .got .data .got.plt .bss 05 .dynamic 06 .ctors .dtors .jcr .dynamic .got 07 .eh_frame_hdr 08 09 .note.tag
See also https://llvm.org/pr26813 for the llvm issue that results in the .text relocations in the first place.
(In reply to Ed Maste from comment #2) That link 404's for me. By the way, if you need/want help in developing or testing a patch, let me know.
Sorry correct link is http://llvm.org/pr26813
A commit references this bug: Author: kib Date: Wed Mar 2 16:36:25 UTC 2016 New revision: 296319 URL: https://svnweb.freebsd.org/changeset/base/296319 Log: Fix handling of DT_TEXTREL for an object with more than one read-only segment. According to gABI spec, presence of the tag indicates that dynamic linker must be prepared to handle relocations against any read-only segment, not only the segment which we, somewhat arbitrary, declared the text. For each read-only segment, add write permission before relocs are processed, and return to the mapping mode requested by the phdr, after relocs are done. Reported, tested, and reviewed by: emaste PR: 207631 Sponsored by: The FreeBSD Foundation MFC after: 2 weeks Changes: head/libexec/rtld-elf/map_object.c head/libexec/rtld-elf/rtld.c head/libexec/rtld-elf/rtld.h
> By the way, if you need/want help in developing or testing a patch, let me know. Thanks for the offer; kib@ had a patch ready pretty quickly to test out.
A commit references this bug: Author: kib Date: Wed Mar 16 15:34:16 UTC 2016 New revision: 296939 URL: https://svnweb.freebsd.org/changeset/base/296939 Log: MFC r296319: Fix handling of DT_TEXTREL for an object with more than one read-only segment. PR: 207631 Changes: _U stable/10/ stable/10/libexec/rtld-elf/map_object.c stable/10/libexec/rtld-elf/rtld.c stable/10/libexec/rtld-elf/rtld.h
No need to merge to stable/9 as new toolchain experiments that prompted this are not relevant there.