From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 32453 invoked by alias); 29 May 2002 19:08:04 -0000 Mailing-List: contact gdb-patches-help@sources.redhat.com; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sources.redhat.com Received: (qmail 32383 invoked from network); 29 May 2002 19:08:00 -0000 Received: from unknown (HELO cygnus.com) (205.180.83.203) by sources.redhat.com with SMTP; 29 May 2002 19:08:00 -0000 Received: from redhat.com (reddwarf.sfbay.redhat.com [172.16.24.50]) by runyon.cygnus.com (8.8.7-cygnus/8.8.7) with ESMTP id MAA15517; Wed, 29 May 2002 12:07:57 -0700 (PDT) Message-ID: <3CF523A0.505903AB@redhat.com> Date: Wed, 29 May 2002 17:02:00 -0000 From: Michael Snyder Organization: Red Hat, Inc. X-Accept-Language: en MIME-Version: 1.0 To: Jim Blandy CC: gdb-patches@sources.redhat.com Subject: Re: Does anybody remember... References: <3CEEC758.2B52BB2A@redhat.com> Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit X-SW-Source: 2002-05/txt/msg01010.txt.bz2 Jim Blandy wrote: > > Michael Snyder writes: > > > Does anybody remember a Harvard Architecture issue, wherein you did > > something > > like take the address of a function, which caused gdb to scrunch the > > address > > down into the target-pointer format and then re-expand it into the > > unified-address > > format, with possible loss of information in the process? > > > > I think Jim Blandy did something to prevent this from happening, > > but it seems to have crept back in again. > > Here's what I think you're referring to, from values.c. The comment > only talks about non-Harvard architectures, but `descriptors' are also > used often in Harvard architectures to keep data and function pointers > the same size even when the code space is much larger than the data > space. OK, good. Now I know what I need to talk to you about, which is: back in April of 2000, you made a change in "locate_var_value" so that, if the var is a function pointer, it will call value_from_pointer instead of value_from_long. This has exactly the same effect as the one you are trying to avoid with the code shown below: the address of the function is crunched down into a pointer (which could be eg. 16 bits), and then later converted back to an address (with loss of information). Can you help me see how to avoid this? > > /* Extract a value as a C pointer. Does not deallocate the value. > Note that val's type may not actually be a pointer; value_as_long > handles all the cases. */ > CORE_ADDR > value_as_address (struct value *val) > { > /* Assume a CORE_ADDR can fit in a LONGEST (for now). Not sure > whether we want this to be true eventually. */ > #if 0 > /* ADDR_BITS_REMOVE is wrong if we are being called for a > non-address (e.g. argument to "signal", "info break", etc.), or > for pointers to char, in which the low bits *are* significant. */ > return ADDR_BITS_REMOVE (value_as_long (val)); > #else > > /* There are several targets (IA-64, PowerPC, and others) which > don't represent pointers to functions as simply the address of > the function's entry point. For example, on the IA-64, a > function pointer points to a two-word descriptor, generated by > the linker, which contains the function's entry point, and the > value the IA-64 "global pointer" register should have --- to > support position-independent code. The linker generates > descriptors only for those functions whose addresses are taken. > > On such targets, it's difficult for GDB to convert an arbitrary > function address into a function pointer; it has to either find > an existing descriptor for that function, or call malloc and > build its own. On some targets, it is impossible for GDB to > build a descriptor at all: the descriptor must contain a jump > instruction; data memory cannot be executed; and code memory > cannot be modified. > > Upon entry to this function, if VAL is a value of type `function' > (that is, TYPE_CODE (VALUE_TYPE (val)) == TYPE_CODE_FUNC), then > VALUE_ADDRESS (val) is the address of the function. This is what > you'll get if you evaluate an expression like `main'. The call > to COERCE_ARRAY below actually does all the usual unary > conversions, which includes converting values of type `function' > to `pointer to function'. This is the challenging conversion > discussed above. Then, `unpack_long' will convert that pointer > back into an address. > > So, suppose the user types `disassemble foo' on an architecture > with a strange function pointer representation, on which GDB > cannot build its own descriptors, and suppose further that `foo' > has no linker-built descriptor. The address->pointer conversion > will signal an error and prevent the command from running, even > though the next step would have been to convert the pointer > directly back into the same address. > > The following shortcut avoids this whole mess. If VAL is a > function, just return its address directly. */ > if (TYPE_CODE (VALUE_TYPE (val)) == TYPE_CODE_FUNC > || TYPE_CODE (VALUE_TYPE (val)) == TYPE_CODE_METHOD) > return VALUE_ADDRESS (val); > > COERCE_ARRAY (val);