From owner-freebsd-current Tue Sep 3 10:57:48 2002 Delivered-To: freebsd-current@freebsd.org Received: from mx1.FreeBSD.org (mx1.FreeBSD.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 7971737B400 for ; Tue, 3 Sep 2002 10:57:42 -0700 (PDT) Received: from mail.gmx.net (mail.gmx.net [213.165.64.20]) by mx1.FreeBSD.org (Postfix) with SMTP id 61E7543E6E for ; Tue, 3 Sep 2002 10:57:40 -0700 (PDT) (envelope-from tmoestl@gmx.net) Received: (qmail 17323 invoked by uid 0); 3 Sep 2002 17:57:37 -0000 Received: from pd9e16c85.dip.t-dialin.net (HELO forge.local) (217.225.108.133) by mail.gmx.net (mp007-rz3) with SMTP; 3 Sep 2002 17:57:37 -0000 Received: from tmm by forge.local with local (Exim 3.36 #1) id 17mHwR-0002rW-00; Tue, 03 Sep 2002 19:58:19 +0200 Date: Tue, 3 Sep 2002 19:58:19 +0200 From: Thomas Moestl To: Peter Wemm Cc: ticso@cicely.de, Alexander Kabaev , ticso@cicely5.cicely.de, des@FreeBSD.ORG, current@FreeBSD.ORG, dillon@freebsd.org Subject: Re: alpha tinderbox failure - kernel is broken. Message-ID: <20020903175819.GA441@crow.dom2ip.de> Mail-Followup-To: Peter Wemm , ticso@cicely.de, Alexander Kabaev , ticso@cicely5.cicely.de, des@FreeBSD.ORG, current@FreeBSD.ORG, dillon@freebsd.org References: <20020903161933.GB80508@cicely5.cicely.de> <20020903163714.049602A7D6@canning.wemm.org> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20020903163714.049602A7D6@canning.wemm.org> User-Agent: Mutt/1.4i Sender: owner-freebsd-current@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.ORG On Tue, 2002/09/03 at 09:37:14 -0700, Peter Wemm wrote: > Bernd Walter wrote: > > On Tue, Sep 03, 2002 at 09:01:07AM -0700, Peter Wemm wrote: > > I was running -current from 2002/08/11 before without any sign about > > this kind of problem. > > Building libiconv failed reproduceable for me, but booting an > > 2002/08/11 kernel made me build the port. > > Yes, imgact_elf.c rev 1.121 is the culprit. Reverting that change solves > the problem. I have attached a patch which, I believe, should fix the problem. I have no alpha box, so I cannot test kernel patches beyond compiling them, so be warned, all below is just a theory, and the patch might of course be broken (so keep kernel.old around :). The problem was caused by the fact that on static executable, the text segment is writable on alpha, so the heuristic prot & VM_PROT_WRITE in the ELF image activator will regard everything as a data segment. This has the (non-fatal) effect that the program text size is regarded to be 0. Much more fatal, however, is that obreak() assumes that all data segments start on consecutive pages (see below). Newer binutils will however place the data segment on the next 64k page at the same offset after the text segment (probably to make it easier for the OS to use super pages), so that holes of more than a page size can occur. obreak() will calculate the heap end address by taking the start of the program data and adding the current data size. The data size of a process is initially set by the image activator; the ELF one sums up the number of 8k-pages actually needed to hold the data. Now, if a "hole" happens to be between the segments that the image activator thinks to hold data, (start address + number of used pages) does of course not suffice to calculate the end address any more. The result is that the vm_map_insert() in obreak() can collide with program segments when trying to insert a mapping starting with the old address (that was calculated incorrectly), so it will fail, causing ENOMEM to be returned. For dynamic executables, this does not occur because the text segment is not writable; the dynamic section, which is writable and executable (because of the plt) starts after the hole and is directly followed by the rest of the data. The attached patch does just change the heuristics used to detect "text" segments to look for executable segments (using an idea from Peter). This results in the fact that dynamic section is viewed as text, which should not break anything. This way, it should be possible to avoid the hole currently; a real fix would be to add a new vmspace field to represent the heap size including holes which could then be used by obreak(), while vm_dsize would only be used for statistics (which is however difficult to maintain when shrinking below the initial size with brk()). Can somebody who is feeling adventurous and has an alpha box please test whether this fixes it for now? Thanks, - Thomas -- Thomas Moestl http://www.tu-bs.de/~y0015675/ http://people.FreeBSD.org/~tmm/ PGP fingerprint: 1C97 A604 2BD0 E492 51D0 9C0F 1FE6 4F1D 419C 776C Index: kern/imgact_elf.c =================================================================== RCS file: /home/ncvs/src/sys/kern/imgact_elf.c,v retrieving revision 1.124 diff -u -r1.124 imgact_elf.c --- kern/imgact_elf.c 2 Sep 2002 17:27:30 -0000 1.124 +++ kern/imgact_elf.c 3 Sep 2002 17:10:21 -0000 @@ -738,14 +738,14 @@ * to distinguish between the two for the purpose * of limit checking and vmspace fields. */ - if (prot & VM_PROT_WRITE) { - data_size += seg_size; - if (data_addr == 0) - data_addr = seg_addr; - } else { + if (prot & VM_PROT_EXECUTE) { text_size += seg_size; if (text_addr == 0) text_addr = seg_addr; + } else { + data_size += seg_size; + if (data_addr == 0) + data_addr = seg_addr; } /* To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-current" in the body of the message