From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 24599 invoked by alias); 8 Nov 2011 05:49:09 -0000 Received: (qmail 24590 invoked by uid 22791); 8 Nov 2011 05:49:07 -0000 X-SWARE-Spam-Status: No, hits=-2.8 required=5.0 tests=AWL,BAYES_00,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from fencepost.gnu.org (HELO fencepost.gnu.org) (140.186.70.10) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Tue, 08 Nov 2011 05:48:49 +0000 Received: from eggs.gnu.org ([140.186.70.92]:58609) by fencepost.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1RNeYA-0006nS-L2 for gcc-help@gnu.org; Tue, 08 Nov 2011 00:48:46 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1RNeY9-000798-4M for gcc-help@gnu.org; Tue, 08 Nov 2011 00:48:46 -0500 Received: from mail-iy0-f169.google.com ([209.85.210.169]:52787) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1RNeY8-000794-Vu for gcc-help@gnu.org; Tue, 08 Nov 2011 00:48:45 -0500 Received: by iaae16 with SMTP id e16so205571iaa.0 for ; Mon, 07 Nov 2011 21:48:43 -0800 (PST) Received: by 10.43.50.67 with SMTP id vd3mr26081887icb.10.1320731323738; Mon, 07 Nov 2011 21:48:43 -0800 (PST) Received: by 10.43.50.67 with SMTP id vd3mr26081870icb.10.1320731323509; Mon, 07 Nov 2011 21:48:43 -0800 (PST) Received: from coign.google.com ([216.239.45.130]) by mx.google.com with ESMTPS id dd36sm658624ibb.7.2011.11.07.21.48.41 (version=TLSv1/SSLv3 cipher=OTHER); Mon, 07 Nov 2011 21:48:42 -0800 (PST) From: Ian Lance Taylor To: Eli Bendersky Cc: gcc-help@gnu.org Subject: Re: why does -fno-pic coge generation on x64 require the large model? References: Date: Tue, 08 Nov 2011 05:49:00 -0000 In-Reply-To: (Eli Bendersky's message of "Tue, 8 Nov 2011 05:18:38 +0200") Message-ID: User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/23.1 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6 (newer, 2) X-Received-From: 209.85.210.169 X-IsSubscribed: yes Mailing-List: contact gcc-help-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-help-owner@gcc.gnu.org X-SW-Source: 2011-11/txt/msg00079.txt.bz2 Eli Bendersky writes: >>> What I'm trying to see is how to convince GCC to generate NON-PIC code >>> and link it into a shared library for x64. I only managed to do this >>> with "-fno-PIC -mcmodel=3Dlarge", and I wonder why with other memory >>> models it doesn't work out. I suspect this has to do with some >>> artifact of x64's addressing modes for symbol offsets. >> >> Yes. =C2=A0If it were easy to permit non-PIC x86_64 code in a shared lib= rary, >> gcc would do it. =C2=A0But the only way to do that is, as you say, to us= e the >> large memory model, which is relatively inefficient. >> > > Yes, I realize this. Hence my original question - *why* is the large > memory model the only way to do it? I know it's relatively > inefficient, because it's the most general and flexible in terms of > addressing. Why aren't the small & medium models flexible enough? It's straightforward if you think about it and try to write down the actual code sequences. To write position independent code you need to be able to write a position independent reference to a global variable which may be defined in a different shared library. When compiling with -fPIC the compiler arranges to load the address of the global variable from the GOT. The dynamic linker fills in the GOT at runtime. The GOT is always in the same shared library, so you can reasonably use a 32-bit PC-relative reference (this assumes that a single shared library will be 2G or less in total address space, which is a reasonable assumption). Of course, you pay the price of a double indirection for each reference to a global variable. When you don't compile with -fPIC, then global variables are referenced directly, rather than via a GOT. When a shared library not loaded in the low 32 bits of memory needs to refer to a global variable loaded in a different shared library also not loaded in the low 32 bits of memory, then the library needs to use a 64-bit address. The compiler will only generate a 64-bit address when using the large model. >> The x86 shared library loader has a kludge where pages that contain >> non-PIC code are remapped and relocated, so every process ends up with >> its own copy of each relocated page. This is provided for >> compatibility with older libraries. x86_64 is a new architecture, so >> it wasn't necessary to provide backwards compatibility for non-PIC >> libraries. > > So non-PIC code on x86_64 is actually different from non-PIC code on > x86? It *doesn't* need page relocation? What's non-PIC about it then, > and again, why only the large memory model allows it? Code on x86 is different from code on x86_64 because it uses a different instruction set. There is no limitation on x86 non-PIC code in a shared library because non-PIC x86 code uses a 32-bit absolute address to refer to a global variable, and that is enough to refer to a shared library loaded anywhere in the address space. Ian