Re: [Dwarf-Discuss] Location list entries for caller-saved registers at time of call
> > This example shows local in %eax, which is a caller-save (i.e., > > scratch) register. GCC is right to show that the value is unknown upon > > return from the call, because set() can clobber that register. > > Sorry, typo -- %eax is a *callee-save* register. Argh! No, I was right the first time. %eax is a caller-save (scratch) register. Here was the typo: > Try changing your code so that you use the value of local after the > call to set() -- say, make it "local += 123" -- and see the > difference. My copy of GCC moves local to %ebx, which is a caller-save > register, and the location list shows it live in that register all the > way through the call and return. %ebx is a *callee-save* (preserved) register. I always have to think twice and I still get callee-save and caller-save backwards! That's why I prefer the terms "scratch" and "preserved". Sorry for the confusion. David correctly said it was a caller-save register in his original mail, and if I hadn't thought "callee-save" instead, I'd have been able to answer his question straight away. -cary ___ Dwarf-Discuss mailing list Dwarf-Discuss@lists.dwarfstd.org http://lists.dwarfstd.org/listinfo.cgi/dwarf-discuss-dwarfstd.org
Re: [Dwarf-Discuss] Location list entries for caller-saved registers at time of call
> > Jakub complains that "the compiler would need to emit a nop after > > every call, which an optimizing compiler is not willing to do." We're > > not talking about *every* call, just the rare case of a no-return > > call. > > They aren't that rare, and even if they would, that is still not enough. > For proper debug info one needs to differentiate between the context inside > of the call and the context right after the call, while in the %eax case > that has been discussed it makes no difference, in others it does. > > Consider: > void bar (void); > void baz (int); > int > foo (void) > { > int a = 6; > bar (); > { > long a = 5; > baz (10); > } > return 10; > } > If you don't subtract one during unwinding and during the bar call look at > foo's frame, then it would appear as if you are already at the baz call with > the inner a variable in scope, but that shouldn't be in scope yet, and if > user asks for value of a, he should see that 6 and its type should be int, > not long. Yes, you're right -- that's a good point. That suggests that perhaps we should do something more explicit to distinguish between "during a call" and "after a call". What happens on architectures where the call instruction is just one addressable unit long? For example, a word-addressed architecture, or Itanium where some toolchains encode the slot number as (0, 1, 2) in the low-order bits of the PC? -cary ___ Dwarf-Discuss mailing list Dwarf-Discuss@lists.dwarfstd.org http://lists.dwarfstd.org/listinfo.cgi/dwarf-discuss-dwarfstd.org
Re: [Dwarf-Discuss] Location list entries for caller-saved registers at time of call
On 12/07/2018 08:12 AM, Jakub Jelinek wrote: On Fri, Dec 07, 2018 at 07:57:23AM -0800, Michael Eager wrote: On 12/07/2018 04:54 AM, Jakub Jelinek wrote: On Fri, Dec 07, 2018 at 12:36:39PM +, David Stenberg via Dwarf-Discuss wrote: For calls, we need to distinguish the locations that are valid in the caller on the call instruction before the call instruction has been executed, then locations that are valid while inside of the call and finally locations that are valid after the call has returned. But the call instruction is atomic. There are not distinct PC locations within an individual call instruction. The instruction itself is, but the invocation of the called procedure is not. So? The return address doesn't slowly creep through the call instruction as the called procedure executes. I know what the PC is before the call, I know what the return address is in the called routine, and I know what the PC is after the return. None of these addresses is in the middle of the call. Why not generate the label as the next address following the call? Because there is some other code there and some other locations might be valid at that point, but not during the call. E.g. something could live in the register holding return value from the function, which won't be there until the function returns. The labels can be: .L0: whatever1 .L1: call foo .L2: whatever2 .L3: and in .debug_loc etc., I can provide say one location description for the range .L0 to .L1 (i.e. for instructions before the call instruction, another one e.g. for .L1 to .L2-1, valid on the call instruction, but not inside of the foo call, another one from .L2-1 to .L2, valid after the call foo instruction is done but before the call returned (i.e. inside of the foo call or whatever it calls) and finally .L2 to .L3 range which covers the instructions after the call. The reason that the loclist is [start, end) is so that you do not need to pretend that there is a valid .L2-1 PC value. There is no valid PC range of [.L1, .L2-1) or [.L2-1, .L2). When inside the called procedure, the return address is .L2, NOT .L2-1. When generating a loclist for the calling function, you don't need to be concerned about the called procedure. All you need to do is list the valid range of PC values in that function. The debug info consumers usually subtract one from the return address with the exception of signal frames so that they locate something in the middle of the call instruction rather than whatever is after it (there could be e.g. a completely different function be there already, or completely unrelated code e.g. for calls that never return). As mentioned before, producers should generate DWARF which describes the code generated, and not attempt to compensate for what it believes a consumer is doing. None of the reasons you give seem to call for generating an invalid PC in the loclist. In the case of a call which is the last instruction in a function. the loclist would have an end address which is after the function. This is OK, and the address is explicitly excluded from the range. -- Michael Eagerea...@eagerm.com 1960 Park Blvd., Palo Alto, CA 94306 ___ Dwarf-Discuss mailing list Dwarf-Discuss@lists.dwarfstd.org http://lists.dwarfstd.org/listinfo.cgi/dwarf-discuss-dwarfstd.org
Re: [Dwarf-Discuss] Location list entries for caller-saved registers at time of call
> Another perfectly good solution is for the compiler to assure that the return > PC is always in the > right scope to begin with. All it takes is to include a (never executed) NOP > following any non-returning > CALL at the last address of the routine.Such calls are not common, plus many > environments align > the beginning of (any subsequent) functions anyway so padding bytes are > likely to be available. As a > result, such "extra" bytes are not going to be a space issue. In fact, the PA-RISC and Itanium calling conventions specifically require this. -cary ___ Dwarf-Discuss mailing list Dwarf-Discuss@lists.dwarfstd.org http://lists.dwarfstd.org/listinfo.cgi/dwarf-discuss-dwarfstd.org