From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 29674 invoked by alias); 9 Jan 2004 23:47:16 -0000 Mailing-List: contact gdb-help@sources.redhat.com; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-owner@sources.redhat.com Received: (qmail 29661 invoked from network); 9 Jan 2004 23:47:14 -0000 Received: from unknown (HELO walton.kettenis.dyndns.org) (213.93.115.144) by sources.redhat.com with SMTP; 9 Jan 2004 23:47:14 -0000 Received: from elgar.kettenis.dyndns.org (elgar.kettenis.dyndns.org [192.168.0.2]) by walton.kettenis.dyndns.org (8.12.6p3/8.12.6) with ESMTP id i09Nl7jv000277; Sat, 10 Jan 2004 00:47:07 +0100 (CET) (envelope-from kettenis@elgar.kettenis.dyndns.org) Received: from elgar.kettenis.dyndns.org (localhost [127.0.0.1]) by elgar.kettenis.dyndns.org (8.12.6p3/8.12.6) with ESMTP id i09Nl7LA000413; Sat, 10 Jan 2004 00:47:07 +0100 (CET) (envelope-from kettenis@elgar.kettenis.dyndns.org) Received: (from kettenis@localhost) by elgar.kettenis.dyndns.org (8.12.6p3/8.12.6/Submit) id i09Nl6RU000410; Sat, 10 Jan 2004 00:47:06 +0100 (CET) Date: Fri, 09 Jan 2004 23:47:00 -0000 Message-Id: <200401092347.i09Nl6RU000410@elgar.kettenis.dyndns.org> From: Mark Kettenis To: cagney@gnu.org CC: gdb@sources.redhat.com In-reply-to: <3FFF0977.3020302@gnu.org> (message from Andrew Cagney on Fri, 09 Jan 2004 15:05:11 -0500) Subject: Re: [RFC] Struct return values References: <200401091622.i09GMRVn000591@elgar.kettenis.dyndns.org> <3FFF0977.3020302@gnu.org> X-SW-Source: 2004-01/txt/msg00133.txt.bz2 Date: Fri, 09 Jan 2004 15:05:11 -0500 From: Andrew Cagney > Recently Andrew did some work on structure return values. The result > was that GDB now refuses to make a function return, that returns a > struct accoriding to the "struct value" convention. The reasoning > behind this is that in general, we can't determine the address of the > bit of memory where we're supposed to return the value if we're in the > middle of such a function. Yep, - no one came up with an ABI that correctly preserved the struct-convention return value address such that it could be extracted at any time including just _after_ a function has returned I guess I wasn't too familiar with SPARC at that moment. For 32-bit SPARC the return value address resides at %sp + 64 in the callers stack frame, which valid until it's overwritten for a new function call. So yes, it is available just after a function has returned. - all the existing ABI which implemented the old extract_struct_value_address did so erreneously vis: > static CORE_ADDR > mips_extract_struct_value_address (struct regcache *regcache) > { > /* FIXME: This will only work at random. The caller passes the > struct_return address in V0, but it is not preserved. It may > still be there, or this may be a random value. */ > LONGEST val; > > regcache_cooked_read_signed (regcache, V0_REGNUM, &val); > return val; > } I believe that this is even true of that old SPARC code. Indeed, the old SPARC code looked at %o0, which is only guaranteed to contain the address when the caller receives control again. The 64-bit SPARC code still does this, and suffers from the same problems as MIPS (although GCC seems to explicitly set %i0/%o0 to the return value address upon return, something that the 64-bit SPARC ABI doesn't seem to require). - the existing extract_struct_value_address, if it were to re-invent itself would needed an interface makeover (arch parameter?, frame parameter?). Certainly. - it only affected new architectures so, as you've done, the developer should notice and report that assumption no longer holds :-). > However, it turns out that with 32-bit > SPARC, we can find out. The SPARC stack frames have a reserved slot > for this address. Should we allow returning in this case? If it's possible to do it robustly ... Is that reserved slot still defined after the return instruction has been executed but before the breakpoint has been hit? Consider the sequence: return breakpoint at return address Yes, the signal handler might touch the register save area at %sp + 0, but should leave alone the return value address at %sp + 64, and everything above that address. I know of two cases: - print_return_value with a tweak round /* FIXME: 2003-09-27: When returning from a nested inferior function call, it's possible (with no help from the architecture vector) to locate and return/print a "struct return" value. This is just a more complicated case of what is already being done in in the inferior function call code. In fact, when inferior function calls are made async, this will likely be made the norm. */ else if (gdbarch_return_value_p (current_gdbarch)) The function has already returned so the method would need to take the callee's frame and return the return value's address. I'm not sure I follow you here, but since the return value address lives at %sp + 64 in the caller's frame, I don't expect any problems. - return_command where the function hasn't yet returned (both the caller and callee frame would be available). Previously this case never worked (I fixed the small structs case)! It would be possible to use call the same method as for print_return_value (passing the caller's frame). Which ever, the doco will need to be really clear that ABI's typically make this impossible :-/ Yes indeed, the 32-bit SPARC ABI is the only case I know of where this stuff is possible. > Furthermore, the testsuite contains the following comment: > > # The struct return case. Since any modification > # would be by reference, and that can't happen, the > # value should be unmodified and hence Z is expected. > # Is this a reasonable assumption? > > I think the answer to the question is "no". It's perfectly allowed > for the caller to provide a bit of scratch memory for the return > value, and copy the contents of this bit of memory to the variable > after the callee returns. Now if we return from a random point in the > callee, the contents of the scratch memory will be undetermined, and > some random bytes will be copied into the variable. This happens for > code generated by the Sun compiler. A way to fix this, is to make > sure that GDB stops immediately after we return from the callee. Is > there an easy way to achieve this? Otherwise, I think we should > refrain from checking the value in this case. I'm suprized that the compiler is generating a double copy, outch! Doesn't make sense to me too, but we're talking about unoptimized code here. The test first does: return foo${n} which leaves the inferior sitting in the caller at the return-to instuction (i.e., "GDB stops immediately after we return from the callee"), and the value sitting in registers or memory. The test then does: -re "Make fun${n} return now.*y or n. $" { gdb_test_multiple "y" "${test}" { -re "L${n} *= fun${n}.*${gdb_prompt} $" { # Need to step off the function call gdb_test "next" "L.* *= fun.*" "${test}" } -re "L[expr ${n} + 1] *= fun[expr ${n} + 1].*${gdb_prompt} $" { pass "${test}" } } } to force the return value into memory at its final destination. Finally the test does the comparison you're seeing: # The struct return case. Since any modification # would be by reference, and that can't happen, the # value should be unmodified and hence Z is expected. # Is this a reasonable assumption? Note that the test needs to ensure that the code storing the return value in memory is executed. That way the test checks for consistency between GDB and the compiler, and not GDB and GDB. What you could look at is: -re ".*${gdb_prompt} $" { if $return_value_unimplemented { # What a suprize. The architecture hasn't implemented # return_value, and hence has to fail. kfail "$test" gdb/1444 } else { fail "$test" } } and soften that test a little (however, if the sparc should work in all cases even that tweak won't be needed). OK, but I think the SPARC case has shown that a compiler can simply generate stupid code that invalidates the assumptions made by the testsuites on other platforms too. -- Since you're looking at this, is there still a need to pass the entire function signature and not just the function's return type to these methods? The sh64 case appears to have evaporated :-( I don't think so, at least not for 32-bit & 64-bit SPARC, IA-32 and AMD64. Mark