From owner-freebsd-ppc@freebsd.org Wed Jun 12 02:55:43 2019 Return-Path: Delivered-To: freebsd-ppc@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 65EF015CD110 for ; Wed, 12 Jun 2019 02:55:43 +0000 (UTC) (envelope-from marklmi@yahoo.com) Received: from sonic306-3.consmr.mail.bf2.yahoo.com (sonic306-3.consmr.mail.bf2.yahoo.com [74.6.132.42]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id BDD398A352 for ; Wed, 12 Jun 2019 02:55:41 +0000 (UTC) (envelope-from marklmi@yahoo.com) X-YMail-OSG: ujxxOJkVM1klOzCC4HbQGNAx4wjwMjJpIAuHGeZgunXOeQiCknDIO7eX0VJJ9h4 vHwnyMU4w24JZAaFS8J8gsggPHcSAw1nfQFYAo1gthUJWX1IV4ygWKqOJP5GG6pYpTngSpnBQ.2F t_J.gOXsajBR.h8qNpPj5atURXZHtEkYcdH7V8VxqyqUA4zU1qN1c5hLV.I4AvGS8eBnWm5NbPml P.sOKWaBum4o5oUy2HGX64fWPt2HM_mR_eW900fDvtx6KIQ2KI0HNm0LHBTY0K0ixSdDTTIXZVPv cX5ifKAmihZir8hoV6wjNATPBaJ5X2zTVZpvyQrATvNu1Vgb9A.MO0QvRjBMUCPjdECIka39tmyi PIEfLmzKaVmWLSCOqG2eyVQ9YMpmfJRYrEOeHNJ.3jQNvQNhfRmx9Jt4tJl7IYdvcnhzLcidOTXl yg2TLg_ZzIVzZ3GSqsLtDQ0fCb_yUHinxTqeeBL9ymcg4xE1toKLP_vLhDpPV8QZoQn4P0j5ymB4 pfnMz1nR1gOgNd9I0vTgZmehMEG6_wVzKSXsFwXJA7BojAX1_u5Glrbkbj1ZWNv4ImjGyvmfcUeQ 2rBaEEuEM3kLiliTCfUXEU66r_m5uPZs.jKxthcQqrbm7sHH812xnvYq7QWnc.kz6Yne7EZtVt1m pNI83nM4aqOSfSNAl0Nu8PsyG4pUzDPIm05Vd0PfLPX7ugEAi9Qrbh2WbTc_nOffXSp4or4Ra9d0 i3A4R6aVY3FLadXD9zoEur3BeYGgBXekP6A3G6TWdJJdJoWvwjUT2sDoaNxBprSwez1CpUFA9fYm v3inTeA4WWdcpG_pHwo4e2fIZdDdt.6o1IJzoSB4HnkdeDEuKVKiUjtn72TY3w1amUJyQUU38a5h cZZl21v7Y0tnAykY8B9WcX7Zzoto6ThwyhDjmTbFBynMOlBi54nfuD49bZKfSwlOFVJhEIa3YUSb QRhMJE1FJm5ZQ7FdQgxUAcu_ZeVD84bGm5y59vLeH3GWmZ7ff4M.RIzqSm4VWKS7n1_Ft9kJDpGO LV2H2MnZ98n.Qul71PwEeWy_Po14V0R_wYjsJ0ghCEr7bp9pq0eqpZ1HW7eB8AVmaPvVBvPHJx0H avsKW_mE7UZdNtqjSWkBpHZqPkyVcIMWUWlyHDNw7pU8EnJ8_TzYM1zD3hA03vxTSLNUf_Jv.KCK cho2WGLoIYyDBZTXLhIn8k1cL0YqxKTivOyYxhWWkmZlCFXRSt9Nqy6Jp0b84qFGPJHHwsKc3QQ- - Received: from sonic.gate.mail.ne1.yahoo.com by sonic306.consmr.mail.bf2.yahoo.com with HTTP; Wed, 12 Jun 2019 02:55:34 +0000 Received: from c-67-170-167-181.hsd1.or.comcast.net (EHLO [192.168.1.115]) ([67.170.167.181]) by smtp429.mail.bf1.yahoo.com (Oath Hermes SMTP Server) with ESMTPA ID d8f426307aa9de76d78aa62e4bebd608; Wed, 12 Jun 2019 02:55:33 +0000 (UTC) Content-Type: text/plain; charset=us-ascii Mime-Version: 1.0 (Mac OS X Mail 12.4 \(3445.104.11\)) Subject: Re: kern_execve using vm_page_zero_invalid but not vm_page_set_validclean to load /sbin/init ? From: Mark Millard In-Reply-To: <48148449-93B0-446C-AA28-F211FFAE1A8B@yahoo.com> Date: Tue, 11 Jun 2019 19:55:31 -0700 Content-Transfer-Encoding: quoted-printable Message-Id: <86F7C4C4-2BB6-40F0-B5D3-C80ECB4A97CF@yahoo.com> References: <1464D960-A1D6-404A-BB10-E615E2D14C1D@yahoo.com> <4003198F-C11B-4587-910B-2001DC09F538@yahoo.com> <47E002B7-D4A1-4C4B-BFFD-D926263D895E@yahoo.com> <48148449-93B0-446C-AA28-F211FFAE1A8B@yahoo.com> To: FreeBSD Hackers , freeBSD PowerPC ML X-Mailer: Apple Mail (2.3445.104.11) X-Rspamd-Queue-Id: BDD398A352 X-Spamd-Bar: +++ X-Spamd-Result: default: False [3.94 / 15.00]; RCVD_VIA_SMTP_AUTH(0.00)[]; R_SPF_ALLOW(-0.20)[+ptr:yahoo.com]; MV_CASE(0.50)[]; FREEMAIL_FROM(0.00)[yahoo.com]; RCVD_COUNT_THREE(0.00)[3]; TO_DN_ALL(0.00)[]; DKIM_TRACE(0.00)[yahoo.com:+]; MX_GOOD(-0.01)[cached: mta6.am0.yahoodns.net]; DMARC_POLICY_ALLOW(-0.50)[yahoo.com,reject]; FROM_EQ_ENVFROM(0.00)[]; MIME_TRACE(0.00)[0:+]; SUBJECT_ENDS_QUESTION(1.00)[]; FREEMAIL_ENVFROM(0.00)[yahoo.com]; ASN(0.00)[asn:26101, ipnet:74.6.128.0/21, country:US]; MID_RHS_MATCH_FROM(0.00)[]; DWL_DNSWL_NONE(0.00)[yahoo.com.dwl.dnswl.org : 127.0.5.0]; ARC_NA(0.00)[]; R_DKIM_ALLOW(-0.20)[yahoo.com:s=s2048]; FROM_HAS_DN(0.00)[]; RCPT_COUNT_THREE(0.00)[4]; NEURAL_SPAM_SHORT(0.91)[0.907,0]; MIME_GOOD(-0.10)[text/plain]; IP_SCORE(1.37)[ip: (4.15), ipnet: 74.6.128.0/21(1.52), asn: 26101(1.22), country: US(-0.06)]; NEURAL_SPAM_MEDIUM(0.28)[0.279,0]; TO_MATCH_ENVRCPT_SOME(0.00)[]; NEURAL_SPAM_LONG(0.90)[0.896,0]; RCVD_IN_DNSWL_NONE(0.00)[42.132.6.74.list.dnswl.org : 127.0.5.0]; RCVD_TLS_LAST(0.00)[] X-BeenThere: freebsd-ppc@freebsd.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Porting FreeBSD to the PowerPC List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 12 Jun 2019 02:55:43 -0000 [I have confirmed .sbss not being zero'd out and environ thereby starting out non-zero (garbage): a debug.minidump=3D0 style dump.] > On 2019-Jun-10, at 16:19, Mark Millard wrote: >=20 > [Forcing an appropriate large .sbss alignment was not enough > to avoid the clang-based problem for *sp++ related environ > code in _init_tls .] >=20 > On 2019-Jun-10, at 12:20, Mark Millard wrote: >=20 >> [I decided to compare some readelf information from some >> other architectures. I was surprised by some of it. But >> .bss seems to be forced to start with a large alignment >> to avoid such issues as I originally traced.] >>=20 >> On 2019-Jun-10, at 11:24, Mark Millard wrote: >>=20 >>> [Looks like Conrad M. is partially confirming my trace of the >>> issue is reasonable.] >>>=20 >>> On 2019-Jun-10, at 07:37, Conrad Meyer wrote: >>>=20 >>>> Hi Mark, >>>>=20 >>>> On Sun, Jun 9, 2019 at 11:17 PM Mark Millard via freebsd-hackers >>>> wrote: >>>>> ... >>>>> vm_pager_get_pages uses vm_page_zero_invalid >>>>> to "Zero out partially filled data". >>>>>=20 >>>>> But vm_page_zero_invalid does not zero every "invalid" >>>>> byte but works in terms of units of DEV_BSIZE : >>>>> ... >>>>> The comment indicates that areas of "sub-DEV_BSIZE" >>>>> should have been handled previously by >>>>> vm_page_set_validclean . >>>>=20 >>>> Or another VM routine, yes (e.g., vm_page_set_valid_range). The = valid >>>> and dirty bitmasks in vm_page only have a single bit per DEV_BSIZE >>>> region, so care must be taken when marking any sub-DEV_BSIZE region = as >>>> valid to zero out the rest of the DEV_BSIZE region. This is part = of >>>> the VM page contract. I'm not sure it's related to the BSS, = though. >>>=20 >>> Yea, I had written from what I'd seen in __elfN(load_section): >>>=20 >>> QUOTE >>> __elfN(load_section) uses vm_imgact_map_page >>> to set up for its copyout. This appears to be >>> how the FileSiz (not including .sbss or .bss) >>> vs. MemSiz (including .sbss and .bss) is >>> handled (attempted?). >>> END QUOTE >>>=20 >>> The copyout only copies through the last byte for filesz >>> but the vm_imgact_map_page does not zero out all the >>> bytes after that on that page: >>>=20 >>> /* >>> * We have to get the remaining bit of the file into the first = part >>> * of the oversized map segment. This is normally because the = .data >>> * segment in the file is extended to provide bss. It's a neat = idea >>> * to try and save a page, but it's a pain in the behind to = implement. >>> */ >>> copy_len =3D filsz =3D=3D 0 ? 0 : (offset + filsz) - = trunc_page(offset + >>> filsz); >>> map_addr =3D trunc_page((vm_offset_t)vmaddr + filsz); >>> map_len =3D round_page((vm_offset_t)vmaddr + memsz) - map_addr; >>> . . . >>> if (copy_len !=3D 0) { >>> sf =3D vm_imgact_map_page(object, offset + filsz); >>> if (sf =3D=3D NULL) >>> return (EIO); >>>=20 >>> /* send the page fragment to user space */ >>> off =3D trunc_page(offset + filsz) - trunc_page(offset = + filsz); >>> error =3D copyout((caddr_t)sf_buf_kva(sf) + off, >>> (caddr_t)map_addr, copy_len); >>> vm_imgact_unmap_page(sf); >>> if (error !=3D 0) >>> return (error); >>> } >>>=20 >>> I looked into the details of the DEV_BSIZE code after sending >>> the original message and so realized that my provided example >>> /sbin/init readelf material was a good example of the issue >>> if I'd not missed something. >>>=20 >>>>> So, if, say, char**environ ends up at the start of .sbss >>>>> consistently, does environ always end up zeroed independently >>>>> of FileSz for the PT_LOAD that spans them? >>>>=20 >>>> It is required to be zeroed, yes. If not, there is a bug. If = FileSz >>>> covers BSS, that's a bug in the linker. Either the trailing bytes = of >>>> the corresponding page in the executable should be zero (wasteful; = on >>>> amd64 ".comment" is packed in there instead), or the linker/loader >>>> must zero them at initialization. I'm not familiar with the >>>> particular details here, but if you are interested I would suggest >>>> looking at __elfN(load_section) in sys/kern/imgact_elf.c. >>>=20 >>> I had looked at it some, see the material around the earlier quote >>> above. >>>=20 >>>>> The following is not necessarily an example of problematical >>>>> figures but is just for showing an example structure of what >>>>> FileSiz covers vs. MemSiz for PT_LOAD's that involve .sbss >>>>> and .bss : >>>>> ... >>>>=20 >>>> Your 2nd LOAD phdr's FileSiz matches up exactly with Segment .sbss >>>> Offset minus Segment .tdata Offset, i.e., none of the FileSiz >>>> corresponds to the (s)bss regions. (Good! At least the static = linker >>>> part looks sane.) That said, the boundary is not page-aligned and = the >>>> section alignment requirement is much lower than page_size, so the >>>> beginning of bss will share a file page with some data. Something >>>> should zero it at image activation. >>>=20 >>> And, so far, I've not found anything in _start or before that does >>> zero any "sub-DEV_BSIZE" part after FileSz for the PT_LOAD in >>> question. >>>=20 >>> Thanks for checking my trace of the issue. It is good to have some >>> confirmation that I'd not missed something. >>>=20 >>>> (Tangent: sbss/bss probably do not need to be RWE on PPC! On = amd64, >>>> init has three LOAD segments rather than two: one for rodata (R), = one >>>> for .text, .init, etc (RX); and one for .data (RW).) >>>=20 >>> Yea, the section header flags indicate just WA for .sbss and .bss = (but >>> WAX for .got). >>>=20 >>> But such is more general: for example, the beginning of .rodata >>> (not executable) shares the tail part of a page with .fini >>> (executable) in the example. .got has executable code but is in >>> the middle of sections that do not. For something like /sbin/init it >>> is so small that the middle of a page can be the only part that is >>> executable, as in the example. (It is not forced onto its own page.) >>>=20 >>> The form of .got used is also writable: WAX for section header = flags. >>=20 >>=20 >>=20 >> amd64's /sbin/init : >>=20 >> There are 9 program headers, starting at offset 64 >>=20 >> Program Headers: >> Type Offset VirtAddr PhysAddr FileSiz = MemSiz Flg Align >> PHDR 0x000040 0x0000000000200040 0x0000000000200040 = 0x0001f8 0x0001f8 R 0x8 >> LOAD 0x000000 0x0000000000200000 0x0000000000200000 = 0x039e94 0x039e94 R 0x1000 >> LOAD 0x03a000 0x000000000023a000 0x000000000023a000 = 0x0e8e40 0x0e8e40 R E 0x1000 >> LOAD 0x123000 0x0000000000323000 0x0000000000323000 = 0x005848 0x2381d9 RW 0x1000 >> TLS 0x127000 0x0000000000327000 0x0000000000327000 = 0x001800 0x001820 R 0x10 >> GNU_RELRO 0x127000 0x0000000000327000 0x0000000000327000 = 0x001848 0x001848 R 0x1 >> GNU_EH_FRAME 0x01b270 0x000000000021b270 0x000000000021b270 = 0x00504c 0x00504c R 0x4 >> GNU_STACK 0x000000 0x0000000000000000 0x0000000000000000 = 0x000000 0x000000 RW 0 >> NOTE 0x000238 0x0000000000200238 0x0000000000200238 = 0x000048 0x000048 R 0x4 >>=20 >> Section to Segment mapping: >> Segment Sections... >> 00 =20 >> 01 .note.tag .rela.plt .rodata .eh_frame_hdr .eh_frame=20 >> 02 .text .init .fini .plt=20 >> 03 .data .got.plt .tdata .tbss .ctors .dtors .jcr .init_array = .fini_array .bss=20 >> 04 .tdata .tbss=20 >> 05 .tdata .tbss .ctors .dtors .jcr .init_array .fini_array=20 >> 06 .eh_frame_hdr=20 >> 07 =20 >> 08 .note.tag=20 >> There are 27 section headers, starting at offset 0x157938: >>=20 >> Section Headers: >> [Nr] Name Type Addr Off Size = ES Flg Lk Inf Al >> [ 0] NULL 0000000000000000 000000 000000 = 00 0 0 0 >> [ 1] .note.tag NOTE 0000000000200238 000238 000048 = 00 A 0 0 4 >> [ 2] .rela.plt RELA 0000000000200280 000280 000030 = 18 AI 0 11 8 >> [ 3] .rodata PROGBITS 00000000002002c0 0002c0 01afb0 = 00 AMS 0 0 64 >> [ 4] .eh_frame_hdr PROGBITS 000000000021b270 01b270 00504c = 00 A 0 0 4 >> [ 5] .eh_frame PROGBITS 00000000002202c0 0202c0 019bd4 = 00 A 0 0 8 >> [ 6] .text PROGBITS 000000000023a000 03a000 0e8dfc = 00 AX 0 0 16 >> [ 7] .init PROGBITS 0000000000322dfc 122dfc 00000e = 00 AX 0 0 4 >> [ 8] .fini PROGBITS 0000000000322e0c 122e0c 00000e = 00 AX 0 0 4 >> [ 9] .plt PROGBITS 0000000000322e20 122e20 000020 = 00 AX 0 0 16 >> [10] .data PROGBITS 0000000000323000 123000 003a80 = 00 WA 0 0 16 >> [11] .got.plt PROGBITS 0000000000326a80 126a80 000010 = 00 WA 0 0 8 >> [12] .tdata PROGBITS 0000000000327000 127000 001800 = 00 WAT 0 0 16 >> [13] .tbss NOBITS 0000000000328800 128800 000020 = 00 WAT 0 0 8 >> [14] .ctors PROGBITS 0000000000328800 128800 000010 = 00 WA 0 0 8 >> [15] .dtors PROGBITS 0000000000328810 128810 000010 = 00 WA 0 0 8 >> [16] .jcr PROGBITS 0000000000328820 128820 000008 = 00 WA 0 0 8 >> [17] .init_array INIT_ARRAY 0000000000328828 128828 000018 = 00 WA 0 0 8 >> [18] .fini_array FINI_ARRAY 0000000000328840 128840 000008 = 00 WA 0 0 8 >> [19] .bss NOBITS 0000000000329000 128848 2321d9 = 00 WA 0 0 64 >> [20] .comment PROGBITS 0000000000000000 128848 0074d4 = 01 MS 0 0 1 >> [21] .gnu.warning.mkte PROGBITS 0000000000000000 12fd1c 000043 = 00 0 0 1 >> [22] .gnu.warning.f_pr PROGBITS 0000000000000000 12fd5f 000043 = 00 0 0 1 >> [23] .gnu_debuglink PROGBITS 0000000000000000 1478b0 000010 = 00 0 0 1 >> [24] .shstrtab STRTAB 0000000000000000 1478c0 0000f1 = 00 0 0 1 >> [25] .symtab SYMTAB 0000000000000000 12fda8 017b08 = 18 26 1707 8 >> [26] .strtab STRTAB 0000000000000000 1479b1 00ff84 = 00 0 0 1 >>=20 >> Note that there is space after .finit_array+8 before .bss starts >> with a sizable alignment. The MemSiz for 03 does span .bss . >>=20 >> armv7's /sbin/init is different about MemSiz spanning .bss: >>=20 >> Program Headers: >> Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg = Align >> PHDR 0x000034 0x00010034 0x00010034 0x00120 0x00120 R 0x4 >> LOAD 0x000000 0x00010000 0x00010000 0x10674 0x10674 R = 0x1000 >> LOAD 0x011000 0x00021000 0x00021000 0xe9c54 0xe9c54 R E = 0x1000 >> LOAD 0x0fb000 0x0010b000 0x0010b000 0x03b88 0x30ccd RW = 0x1000 >> TLS 0x0fe000 0x0010e000 0x0010e000 0x00b60 0x00b70 R = 0x20 >> GNU_RELRO 0x0fe000 0x0010e000 0x0010e000 0x00b88 0x00b88 R 0x1 >> GNU_STACK 0x000000 0x00000000 0x00000000 0x00000 0x00000 RW 0 >> NOTE 0x000154 0x00010154 0x00010154 0x00064 0x00064 R 0x4 >> ARM_EXIDX 0x0001b8 0x000101b8 0x000101b8 0x00220 0x00220 R 0x4 >>=20 >> (NOTE: 0x0010b000+0x30ccd=3D=3D0x13BCCD . Compare this to the later = .bss >> Addr of 0x10f000.) >>=20 >> Section to Segment mapping: >> Segment Sections... >> 00 =20 >> 01 .note.tag .ARM.exidx .rodata .ARM.extab=20 >> 02 .text .init .fini=20 >> 03 .data .tdata .tbss .jcr .init_array .fini_array .got .bss=20 >> 04 .tdata .tbss=20 >> 05 .tdata .tbss .jcr .init_array .fini_array .got=20 >> 06 =20 >> 07 .note.tag=20 >> 08 .ARM.exidx=20 >> There are 24 section headers, starting at offset 0x12be3c: >>=20 >> Section Headers: >> [Nr] Name Type Addr Off Size ES Flg = Lk Inf Al >> [ 0] NULL 00000000 000000 000000 00 = 0 0 0 >> [ 1] .note.tag NOTE 00010154 000154 000064 00 A = 0 0 4 >> [ 2] .ARM.exidx ARM_EXIDX 000101b8 0001b8 000220 00 A = 5 0 4 >> [ 3] .rodata PROGBITS 00010400 000400 01022c 00 AMS = 0 0 64 >> [ 4] .ARM.extab PROGBITS 0002062c 01062c 000048 00 A = 0 0 4 >> [ 5] .text PROGBITS 00021000 011000 0e9c14 00 AX = 0 0 128 >> [ 6] .init PROGBITS 0010ac20 0fac20 000014 00 AX = 0 0 16 >> [ 7] .fini PROGBITS 0010ac40 0fac40 000014 00 AX = 0 0 16 >> [ 8] .data PROGBITS 0010b000 0fb000 002734 00 WA = 0 0 8 >> [ 9] .tdata PROGBITS 0010e000 0fe000 000b60 00 WAT = 0 0 16 >> [10] .tbss NOBITS 0010eb60 0feb60 000010 00 WAT = 0 0 4 >> [11] .jcr PROGBITS 0010eb60 0feb60 000000 00 WA = 0 0 4 >> [12] .init_array INIT_ARRAY 0010eb60 0feb60 000008 00 WA = 0 0 4 >> [13] .fini_array FINI_ARRAY 0010eb68 0feb68 000004 00 WA = 0 0 4 >> [14] .got PROGBITS 0010eb6c 0feb6c 00001c 00 WA = 0 0 4 >> [15] .bss NOBITS 0010f000 0feb88 02cccd 00 WA = 0 0 64 >> [16] .comment PROGBITS 00000000 0feb88 0074b6 01 MS = 0 0 1 >> [17] .ARM.attributes ARM_ATTRIBUTES 00000000 10603e 00004f 00 = 0 0 1 >> [18] .gnu.warning.mkte PROGBITS 00000000 10608d 000043 00 = 0 0 1 >> [19] .gnu.warning.f_pr PROGBITS 00000000 1060d0 000043 00 = 0 0 1 >> [20] .gnu_debuglink PROGBITS 00000000 11b314 000010 00 = 0 0 1 >> [21] .shstrtab STRTAB 00000000 11b324 0000e3 00 = 0 0 1 >> [22] .symtab SYMTAB 00000000 106114 015200 10 = 23 3063 4 >> [23] .strtab STRTAB 00000000 11b407 010a32 00 = 0 0 1 >>=20 >> Note that there is space after .got+0x1c before .bss starts >> with a sizable alignment. The MemSiz for 03 does *not* span >> .bss , unlike for amd64 (and the rest). >>=20 >>=20 >> aarch64's /sbin/init is similar to amd64 instead of armv7: >>=20 >> Program Headers: >> Type Offset VirtAddr PhysAddr FileSiz = MemSiz Flg Align >> PHDR 0x000040 0x0000000000200040 0x0000000000200040 = 0x0001c0 0x0001c0 R 0x8 >> LOAD 0x000000 0x0000000000200000 0x0000000000200000 = 0x01624f 0x01624f R 0x10000 >> LOAD 0x020000 0x0000000000220000 0x0000000000220000 = 0x0dd354 0x0dd354 R E 0x10000 >> LOAD 0x100000 0x0000000000300000 0x0000000000300000 = 0x011840 0x252111 RW 0x10000 >> TLS 0x110000 0x0000000000310000 0x0000000000310000 = 0x001800 0x001820 R 0x40 >> GNU_RELRO 0x110000 0x0000000000310000 0x0000000000310000 = 0x001840 0x001840 R 0x1 >> GNU_STACK 0x000000 0x0000000000000000 0x0000000000000000 = 0x000000 0x000000 RW 0 >> NOTE 0x000200 0x0000000000200200 0x0000000000200200 = 0x000048 0x000048 R 0x4 >>=20 >> Section to Segment mapping: >> Segment Sections... >> 00 =20 >> 01 .note.tag .rodata=20 >> 02 .text .init .fini=20 >> 03 .data .tdata .tbss .jcr .init_array .fini_array .got .bss=20 >> 04 .tdata .tbss=20 >> 05 .tdata .tbss .jcr .init_array .fini_array .got=20 >> 06 =20 >> 07 .note.tag=20 >> There are 21 section headers, starting at offset 0x14b6f0: >>=20 >> Section Headers: >> [Nr] Name Type Addr Off Size = ES Flg Lk Inf Al >> [ 0] NULL 0000000000000000 000000 000000 = 00 0 0 0 >> [ 1] .note.tag NOTE 0000000000200200 000200 000048 = 00 A 0 0 4 >> [ 2] .rodata PROGBITS 0000000000200280 000280 015fcf = 00 AMS 0 0 64 >> [ 3] .text PROGBITS 0000000000220000 020000 0dd31c = 00 AX 0 0 64 >> [ 4] .init PROGBITS 00000000002fd320 0fd320 000014 = 00 AX 0 0 16 >> [ 5] .fini PROGBITS 00000000002fd340 0fd340 000014 = 00 AX 0 0 16 >> [ 6] .data PROGBITS 0000000000300000 100000 003a20 = 00 WA 0 0 16 >> [ 7] .tdata PROGBITS 0000000000310000 110000 001800 = 00 WAT 0 0 16 >> [ 8] .tbss NOBITS 0000000000311800 111800 000020 = 00 WAT 0 0 8 >> [ 9] .jcr PROGBITS 0000000000311800 111800 000000 = 00 WA 0 0 8 >> [10] .init_array INIT_ARRAY 0000000000311800 111800 000018 = 00 WA 0 0 8 >> [11] .fini_array FINI_ARRAY 0000000000311818 111818 000008 = 00 WA 0 0 8 >> [12] .got PROGBITS 0000000000311820 111820 000020 = 00 WA 0 0 8 >> [13] .bss NOBITS 0000000000320000 111840 232111 = 00 WA 0 0 64 >> [14] .comment PROGBITS 0000000000000000 111840 007191 = 01 MS 0 0 1 >> [15] .gnu.warning.mkte PROGBITS 0000000000000000 1189d1 000043 = 00 0 0 1 >> [16] .gnu.warning.f_pr PROGBITS 0000000000000000 118a14 000043 = 00 0 0 1 >> [17] .gnu_debuglink PROGBITS 0000000000000000 13b7f8 000010 = 00 0 0 1 >> [18] .shstrtab STRTAB 0000000000000000 13b808 0000bd = 00 0 0 1 >> [19] .symtab SYMTAB 0000000000000000 118a58 022da0 = 18 20 3621 8 >> [20] .strtab STRTAB 0000000000000000 13b8c5 00fe2b = 00 0 0 1 >>=20 >> Note that there is space after .got+0x20 before .bss starts >> with a sizable alignment. The MemSiz for 03 does span >> .bss , like for amd64 (and all but armv7). >>=20 >> powerpc64's /sbin/init is similar to amd64 as well: >>=20 >> Program Headers: >> Type Offset VirtAddr PhysAddr FileSiz = MemSiz Flg Align >> PHDR 0x000040 0x0000000000200040 0x0000000000200040 = 0x0001f8 0x0001f8 R 0x8 >> LOAD 0x000000 0x0000000000200000 0x0000000000200000 = 0x039e94 0x039e94 R 0x1000 >> LOAD 0x03a000 0x000000000023a000 0x000000000023a000 = 0x0e8e40 0x0e8e40 R E 0x1000 >> LOAD 0x123000 0x0000000000323000 0x0000000000323000 = 0x005848 0x2381d9 RW 0x1000 >> TLS 0x127000 0x0000000000327000 0x0000000000327000 = 0x001800 0x001820 R 0x10 >> GNU_RELRO 0x127000 0x0000000000327000 0x0000000000327000 = 0x001848 0x001848 R 0x1 >> GNU_EH_FRAME 0x01b270 0x000000000021b270 0x000000000021b270 = 0x00504c 0x00504c R 0x4 >> GNU_STACK 0x000000 0x0000000000000000 0x0000000000000000 = 0x000000 0x000000 RW 0 >> NOTE 0x000238 0x0000000000200238 0x0000000000200238 = 0x000048 0x000048 R 0x4 >>=20 >> Section to Segment mapping: >> Segment Sections... >> 00 =20 >> 01 .note.tag .rela.plt .rodata .eh_frame_hdr .eh_frame=20 >> 02 .text .init .fini .plt=20 >> 03 .data .got.plt .tdata .tbss .ctors .dtors .jcr .init_array = .fini_array .bss=20 >> 04 .tdata .tbss=20 >> 05 .tdata .tbss .ctors .dtors .jcr .init_array .fini_array=20 >> 06 .eh_frame_hdr=20 >> 07 =20 >> 08 .note.tag=20 >> There are 27 section headers, starting at offset 0x157938: >>=20 >> Section Headers: >> [Nr] Name Type Addr Off Size = ES Flg Lk Inf Al >> [ 0] NULL 0000000000000000 000000 000000 = 00 0 0 0 >> [ 1] .note.tag NOTE 0000000000200238 000238 000048 = 00 A 0 0 4 >> [ 2] .rela.plt RELA 0000000000200280 000280 000030 = 18 AI 0 11 8 >> [ 3] .rodata PROGBITS 00000000002002c0 0002c0 01afb0 = 00 AMS 0 0 64 >> [ 4] .eh_frame_hdr PROGBITS 000000000021b270 01b270 00504c = 00 A 0 0 4 >> [ 5] .eh_frame PROGBITS 00000000002202c0 0202c0 019bd4 = 00 A 0 0 8 >> [ 6] .text PROGBITS 000000000023a000 03a000 0e8dfc = 00 AX 0 0 16 >> [ 7] .init PROGBITS 0000000000322dfc 122dfc 00000e = 00 AX 0 0 4 >> [ 8] .fini PROGBITS 0000000000322e0c 122e0c 00000e = 00 AX 0 0 4 >> [ 9] .plt PROGBITS 0000000000322e20 122e20 000020 = 00 AX 0 0 16 >> [10] .data PROGBITS 0000000000323000 123000 003a80 = 00 WA 0 0 16 >> [11] .got.plt PROGBITS 0000000000326a80 126a80 000010 = 00 WA 0 0 8 >> [12] .tdata PROGBITS 0000000000327000 127000 001800 = 00 WAT 0 0 16 >> [13] .tbss NOBITS 0000000000328800 128800 000020 = 00 WAT 0 0 8 >> [14] .ctors PROGBITS 0000000000328800 128800 000010 = 00 WA 0 0 8 >> [15] .dtors PROGBITS 0000000000328810 128810 000010 = 00 WA 0 0 8 >> [16] .jcr PROGBITS 0000000000328820 128820 000008 = 00 WA 0 0 8 >> [17] .init_array INIT_ARRAY 0000000000328828 128828 000018 = 00 WA 0 0 8 >> [18] .fini_array FINI_ARRAY 0000000000328840 128840 000008 = 00 WA 0 0 8 >> [19] .bss NOBITS 0000000000329000 128848 2321d9 = 00 WA 0 0 64 >> [20] .comment PROGBITS 0000000000000000 128848 0074d4 = 01 MS 0 0 1 >> [21] .gnu.warning.mkte PROGBITS 0000000000000000 12fd1c 000043 = 00 0 0 1 >> [22] .gnu.warning.f_pr PROGBITS 0000000000000000 12fd5f 000043 = 00 0 0 1 >> [23] .gnu_debuglink PROGBITS 0000000000000000 1478b0 000010 = 00 0 0 1 >> [24] .shstrtab STRTAB 0000000000000000 1478c0 0000f1 = 00 0 0 1 >> [25] .symtab SYMTAB 0000000000000000 12fda8 017b08 = 18 26 1707 8 >> [26] .strtab STRTAB 0000000000000000 1479b1 00ff84 = 00 0 0 1 >>=20 >>=20 >> Note that there is space after .fini_array+8 before .bss starts >> with a sizable alignment. The MemSiz for 03 does span >> .bss , like for amd64 (and all but armv7). >=20 > I temporarily forced my 32-bit powerpc /sbin/init to have: >=20 > Section Headers: > [Nr] Name Type Addr Off Size ES Flg = Lk Inf Al > . . . > [16] .got PROGBITS 0193845c 12845c 000010 04 WAX = 0 0 4 > [17] .sbss NOBITS 01939000 12846c 0000b0 00 WA = 0 0 4 > [18] .bss NOBITS 019390c0 12846c 02cc48 00 WA = 0 0 64 > . . . >=20 > It was not enough to avoid the problems I've elsewhere > reported for *sp++ getting SIGSEGV ( environ related > activity in _init_tls ). I used debug.minidump=3D0 in /boot/loader.conf for cusing a dump for the crash and a libkvm modified enough for my working boot environment to allow me to examine the the memory-image bytes of such a dump, with libkvm used via /usr/local/bin/kgdb . (No support of automatically translating user-space addresses or other such.) For the clang based debug buildworld and debug buildkernel context with /sbin/init having: [16] .got PROGBITS 01956ccc 146ccc 000010 04 WAX = 0 0 4 [17] .sbss NOBITS 01956cdc 146cdc 0000b0 00 WA = 0 0 4 [18] .bss NOBITS 01956dc0 146cdc 02ee28 00 WA = 0 0 64 I confirmed that .sbss in /sbin/init's address space is not zeroed (so environ is not assigned by handle_argv ). I also confirmed that _start was given a good env value (in %r5) based on where the value was stored on the stack. It is just that the value was not used. The detailed obvious-failure point (crash) can change based on the garbage in the .sbss and, for the build that I used this time, that happened in __je_arean_malloc_hard instead of before _init_tls called _libc_allocate_tls . (I traced the call chain in the dump.) =46rom what I've seen in the dump there seem to be special uses of some values (that also have normal uses, of course): 0xfa5005af: as yet invalid page content. 0x1c000020: as yet unassigned user-space-stack memory for /sbin/init. These are the same locations that I previously reported as showing up in the DSI read trap reports for /sbin/init failing. The specific build here failed with a different value. For reference relative to libkvm: # svnlite diff /usr/src/lib/libkvm/ Index: /usr/src/lib/libkvm/kvm_powerpc.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- /usr/src/lib/libkvm/kvm_powerpc.c (revision 347549) +++ /usr/src/lib/libkvm/kvm_powerpc.c (working copy) @@ -211,6 +211,53 @@ if (be32toh(vm->ph->p_paddr) =3D=3D 0xffffffff) return ((int)powerpc_va2off(kd, va, ofs)); =20 + // HACK in something for what I observe in + // a debug.minidump=3D0 vmcore.* for 32-bit powerpc + // + if ( be32toh(vm->ph->p_vaddr) =3D=3D 0xffffffff + && be32toh(vm->ph->p_paddr) =3D=3D 0 + && be16toh(vm->eh->e_phnum) =3D=3D 1 + ) { + // Presumes p_memsz is either unsigned + // 32-bit or is 64-bit, same for va . + + if (be32toh(vm->ph->p_memsz) <=3D va) + return 0; // Like powerpc_va2off + + // If ofs was (signed) 32-bit there + // would be a problem for sufficiently + // large postive memsz's and va's + // near the end --because of p_offset + // and dmphdrsz causing overflow/wrapping + // for some large va values. + // Presumes 64-bit ofs for such cases. + // Also presumes dmphdrsz+p_offset + // is non-negative so that small + // non-negative va values have no + // problems with ofs going negative. + + *ofs =3D vm->dmphdrsz + + be32toh(vm->ph->p_offset) + + va; + + // The normal return value overflows/wraps + // for p_memsz =3D=3D 0x80000000u when va =3D=3D 0 . + // Avoid this by depending on calling code's + // loop for sufficiently large cases. + // This code presumes p_memsz/2 <=3D MAX_INT . + // 32-bit powerpc FreeBSD does not allow + // using more than 2 GiBytes of RAM but + // does allow using 2 GiBytes on 64-bit + // hardware. + // + if ( (int)be32toh(vm->ph->p_memsz) < 0 + && va < be32toh(vm->ph->p_memsz)/2 + ) + return be32toh(vm->ph->p_memsz)/2; + + return be32toh(vm->ph->p_memsz) - va; + } + _kvm_err(kd, kd->program, "Raw corefile not supported"); return (0); } Index: /usr/src/lib/libkvm/kvm_private.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- /usr/src/lib/libkvm/kvm_private.c (revision 347549) +++ /usr/src/lib/libkvm/kvm_private.c (working copy) @@ -131,7 +131,9 @@ { =20 return (kd->nlehdr.e_ident[EI_CLASS] =3D=3D class && - kd->nlehdr.e_type =3D=3D ET_EXEC && + ( kd->nlehdr.e_type =3D=3D ET_EXEC || + kd->nlehdr.e_type =3D=3D ET_DYN + ) && kd->nlehdr.e_machine =3D=3D machine); } =20 =3D=3D=3D Mark Millard marklmi at yahoo.com ( dsl-only.net went away in early 2018-Mar)