From patchwork Thu Dec 8 12:09:38 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nick Clifton X-Patchwork-Id: 87237 Delivered-To: patch@linaro.org Received: by 10.140.20.101 with SMTP id 92csp809423qgi; Thu, 8 Dec 2016 04:10:13 -0800 (PST) X-Received: by 10.84.177.129 with SMTP id x1mr152356000plb.105.1481199013118; Thu, 08 Dec 2016 04:10:13 -0800 (PST) Return-Path: Received: from sourceware.org (server1.sourceware.org. [209.132.180.131]) by mx.google.com with ESMTPS id r14si28574282pli.223.2016.12.08.04.10.12 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 08 Dec 2016 04:10:13 -0800 (PST) Received-SPF: pass (google.com: domain of binutils-return-94804-patch=linaro.org@sourceware.org designates 209.132.180.131 as permitted sender) client-ip=209.132.180.131; Authentication-Results: mx.google.com; dkim=pass header.i=@sourceware.org; spf=pass (google.com: domain of binutils-return-94804-patch=linaro.org@sourceware.org designates 209.132.180.131 as permitted sender) smtp.mailfrom=binutils-return-94804-patch=linaro.org@sourceware.org DomainKey-Signature: a=rsa-sha1; c=nofws; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:subject:to:references:cc:from:message-id:date :mime-version:in-reply-to:content-type; q=dns; s=default; b=rf7e 2RlnFcHOlCUUhyNBzhk/I1x00O49VeYma3dghqIKwj4CwaHmIn8xRlQD2jvix9rz L312miefip2OTUcOiHbVGwACB8qX4z/PVoIBqMRNaMun+VXA3/vH27A45J5HmieA oz5/f5L8rSM/WJeLd+wwKC9TT5kHC3VWhqWcuoE= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:subject:to:references:cc:from:message-id:date :mime-version:in-reply-to:content-type; s=default; bh=I6DgFDVOCL 8cWEm3N9AcCN6I1hk=; b=rdDxBUfq0qNq4EprmZvv9yg+znFoH4T4vHzyUDnzy1 SPeIxYcmz2zZcpmoPA2LyO8/9QBAa5UK5Y2YXKs+IspKrKFWOXQ7FAPO0jSJFoqJ sVOs3BldGvK0J7FtM76G3W9lYTEc1KXRWHMzy65ExqhrV1QTizAObS/UVCojXdlL c= Received: (qmail 73451 invoked by alias); 8 Dec 2016 12:09:54 -0000 Mailing-List: contact binutils-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: binutils-owner@sourceware.org Delivered-To: mailing list binutils@sourceware.org Received: (qmail 73427 invoked by uid 89); 8 Dec 2016 12:09:52 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-3.9 required=5.0 tests=BAYES_00, KAM_LAZY_DOMAIN_SECURITY, RP_MATCHES_RCVD, SPF_HELO_PASS autolearn=ham version=3.3.2 spammy=loadable, PT_PHDR, pt_phdr, controlled X-Spam-User: qpsmtpd, 2 recipients X-HELO: mx1.redhat.com Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Thu, 08 Dec 2016 12:09:42 +0000 Received: from int-mx10.intmail.prod.int.phx2.redhat.com (int-mx10.intmail.prod.int.phx2.redhat.com [10.5.11.23]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 422A4624C0; Thu, 8 Dec 2016 12:09:41 +0000 (UTC) Received: from [10.36.126.3] ([10.36.126.3]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id uB8C9dDU012745 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Thu, 8 Dec 2016 07:09:40 -0500 Subject: Re: [binutils-gdb] Fix the linker so that it will not silently generate ELF binaries with invalid program headers. Fix To: "Maciej W. Rozycki" , Nick Clifton References: <20161123111226.62132.qmail@sourceware.org> Cc: binutils@sourceware.org From: Nick Clifton Message-ID: <16bd18c6-f179-856c-a587-b2dc683b1954@redhat.com> Date: Thu, 8 Dec 2016 12:09:38 +0000 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101 Thunderbird/45.5.1 MIME-Version: 1.0 In-Reply-To: X-IsSubscribed: yes Hi Maciej, > Program Headers: > Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align > PHDR 0x000034 0x00001034 0x00000000 0x000a0 0x000a0 R E 0x4 > INTERP 0x001000 0x00080000 0x00080000 0x00013 0x00013 R 0x1 > [Requesting program interpreter: /usr/lib/libc.so.1] > LOAD 0x001000 0x00080000 0x00080000 0x00408 0x00408 R E 0x1000 > LOAD 0x002000 0x00081000 0x00081000 0x00804 0x00c00 RW 0x1000 > DYNAMIC 0x002000 0x00081000 0x00081000 0x00078 0x00078 RW 0x4 The problem with this layout is that the ELF specification says in its description of the program header types: PT_PHDR The array element, if present, specifies the location and size of the program header table itself, both in the file and in the memory image of the program. This segment type may not occur more than once in a file. Moreover, it may occur only if the program header table is part of the memory image of the program. If it is present, it must precede any loadable segment entry. Hence, if a PT_PHDR segment is present in a binary it must also be part of a PT_LOAD segment, so that it gets loaded into the runtime memory image of the executable. The layout above breaks this requirement by placing the PT_PHDR segment at 0x1034 but starting the first load segment at 0x80000. > Program Headers: > Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align > PHDR 0x000034 0x0007f034 0x0007f034 0x000a0 0x000a0 R E 0x4 > INTERP 0x001000 0x00080000 0x00080000 0x00013 0x00013 R 0x1 > [Requesting program interpreter: /usr/lib/libc.so.1] > LOAD 0x000000 0x0007f000 0x0007f000 0x01408 0x01408 R E 0x1000 > LOAD 0x002000 0x00081000 0x00081000 0x00804 0x00c00 RW 0x1000 > DYNAMIC 0x002000 0x00081000 0x00081000 0x00078 0x00078 RW 0x4 This is the linker's attempt to resolve the problem, by moving the start address of the first LOAD segment down to 0x7f0000. (The linker cannot just create another LOAD segment just for the program headers as there is code inside the linker that will discard any LOAD segments that do not have any sections mapped into them). > This places the first LOAD segment below the location set with the linker > script, which I fear may affect run-time interpretation. The test case > has the addresses expected spelled out in full for a reason I suppose. True. You could fix the problem by adding --no-dynamic-linker to the test's linker command line, since then the linker will not create PHDR or INTERP segments, and so the LOAD segments will have the expected addresses. I doubt if you want this solution however as I assume that the whole point of this test is to create a working dynamic executable. The correct solution, I think, is to define the program headers in the linker script, so that their placement can be specifically controlled by the user. See the vxworks1.ld script attached, which does this. But...this causes a problem for the "VxWorks executable test 2 (static)" test as now there is a DYNAMIC segment in the program headers but no .dynamic section in the section headers, and readelf complains. *sigh* So you need a second linker script, just for static executables. So the result is the attached patch, which I think resolves the problem. (For MIPS based vxworks targets anyway. It looks like similar changes may be needed for other vxworks architectures). What do you think ? Cheers Nick PHDRS { headers PT_PHDR PHDRS; header_load PT_LOAD PHDRS; interp PT_INTERP; code PT_LOAD; data PT_LOAD; dynamic PT_DYNAMIC; } SECTIONS { . = 0x80000; . = . + SIZEOF_HEADERS; .interp : { *(.interp) } :interp :headers :header_load .hash : { *(.hash) } :code .dynsym : { *(.dynsym) } .dynstr : { *(.dynstr) } . = ALIGN (0x400); .rela.dyn : { *(.rela.dyn) } .rela.plt : { *(.rela.plt) } . = ALIGN (0x400); .plt : { *(.plt) } . = ALIGN (0x400); .text : { *(.text) } . = ALIGN (0x1000); .dynamic : { *(.dynamic) } :data :dynamic . = ALIGN (0x400); .got : { *(.got.plt) *(.got) } :data . = ALIGN (0x400); .data : { *(.data) } . = ALIGN (0x400); .bss : { *(.bss) *(.dynbss) } /DISCARD/ : { *(.reginfo) *(.MIPS.abiflags) } } diff --git a/ld/testsuite/ld-mips-elf/mips-elf.exp b/ld/testsuite/ld-mips-elf/mips-elf.exp index fd79e80..b12d1b7 100644 --- a/ld/testsuite/ld-mips-elf/mips-elf.exp +++ b/ld/testsuite/ld-mips-elf/mips-elf.exp @@ -37,7 +37,7 @@ if {[istarget "mips*-*-vxworks"]} { {{readelf --segments vxworks2.sd}} "vxworks2"} {"VxWorks executable test 2 (static)" - "-Tvxworks1.ld" "" + "-Tvxworks2-static.ld" "" "-mips2" {vxworks2.s} {{readelf --segments vxworks2-static.sd}} "vxworks2"} diff --git a/ld/testsuite/ld-mips-elf/vxworks1.ld b/ld/testsuite/ld-mips-elf/vxworks1.ld index d9f8621..428564c 100644 --- a/ld/testsuite/ld-mips-elf/vxworks1.ld +++ b/ld/testsuite/ld-mips-elf/vxworks1.ld @@ -1,8 +1,19 @@ +PHDRS +{ + headers PT_PHDR PHDRS; + header_load PT_LOAD PHDRS; + interp PT_INTERP; + code PT_LOAD; + data PT_LOAD; + dynamic PT_DYNAMIC; +} + SECTIONS { . = 0x80000; - .interp : { *(.interp) } - .hash : { *(.hash) } + . = . + SIZEOF_HEADERS; + .interp : { *(.interp) } :interp :headers :header_load + .hash : { *(.hash) } :code .dynsym : { *(.dynsym) } .dynstr : { *(.dynstr) } @@ -17,10 +28,10 @@ SECTIONS .text : { *(.text) } . = ALIGN (0x1000); - .dynamic : { *(.dynamic) } + .dynamic : { *(.dynamic) } :data :dynamic . = ALIGN (0x400); - .got : { *(.got.plt) *(.got) } + .got : { *(.got.plt) *(.got) } :data . = ALIGN (0x400); .data : { *(.data) } @@ -28,5 +39,6 @@ SECTIONS . = ALIGN (0x400); .bss : { *(.bss) *(.dynbss) } + /DISCARD/ : { *(.reginfo) *(.MIPS.abiflags) } } diff --git a/ld/testsuite/ld-mips-elf/vxworks2.sd b/ld/testsuite/ld-mips-elf/vxworks2.sd index 5ff87d3..01301ba 100644 --- a/ld/testsuite/ld-mips-elf/vxworks2.sd +++ b/ld/testsuite/ld-mips-elf/vxworks2.sd @@ -6,8 +6,8 @@ Program Headers: Type .* PHDR .* #... - LOAD .* 0x00080000 0x00080000 .* R E 0x1000 - LOAD .* 0x00081000 0x00081000 .* RW 0x1000 + LOAD .* 0x00080... 0x00080... .* R E 0x1000 + LOAD .* 0x00081... 0x00081... .* RW 0x1000 DYNAMIC .* #... --- /dev/null 2016-12-08 07:35:33.885870158 +0000 +++ ld/testsuite/ld-mips-elf/vxworks2-static.ld 2016-12-08 12:04:17.091239541 +0000 @@ -0,0 +1,25 @@ +SECTIONS +{ + . = 0x80000; + .hash : { *(.hash) } + + . = ALIGN (0x400); + .rela.plt : { *(.rela.plt) } + + . = ALIGN (0x400); + .plt : { *(.plt) } + + . = ALIGN (0x400); + .text : { *(.text) } + + . = ALIGN (0x1000); + .got : { *(.got.plt) *(.got) } + + . = ALIGN (0x400); + .data : { *(.data) } + + . = ALIGN (0x400); + .bss : { *(.bss) *(.dynbss) } + + /DISCARD/ : { *(.reginfo) *(.MIPS.abiflags) } +}