[Dwarf-Discuss] Location list entries for caller-saved registers at time of call

2018-12-06 Thread David Stenberg via Dwarf-Discuss
Hi!

When GDB and LLDB perform virtual unwinding, they subtract one byte
from the return addresses of the outer frames. This is for example
necessary when unwinding from a non-returning call that is placed last
in the function, as the return address then can point to a different
function. I assume that this is also necessary to get the variables
that were in scope at the time of the call, and the right location
expressions for the variables, etc.

As far as I have understood it, GCC utilizes this fact for location
list entries that are expressed in caller-saved registers, by
subtracting one from the (exclusive) ending address of the entries.
This means that variables in outer frames that are located in caller-
saved registers will be printed out as  by GDB.

I have not been able to find anything in the DWARF standard that
describes this. Is this something that is defined by standard, or is it
established praxis between GCC and GDB? If the latter, do you know of
other producers and consumers that behave like this?

The reason why I ask this is because Clang/LLVM at the moment ends
location list entries expressed in caller-saved registers at the first
instruction after the call. This means that variables in outer frames
using such location list entries will incorrectly be evaluated using
the inner-most frame's register values when debugging in GDB.

(As a side note, as far as I have understood it, LLDB has fallback
knowledge of the ABI, so caller-saved registers will be considered
unavailable in outer frames, meaning that such location list entries
are not an issue when combining Clang/LLVM and LLDB.)

Best regards,
David
___
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

2018-12-06 Thread David Stenberg via Dwarf-Discuss
On tor, 2018-12-06 at 16:32 +0100, Andreas Arnez via Dwarf-Discuss
wrote:
> If GDB uses caller-saved register values from the inner-most frame in
> outer frames, then this is a bug.  Note that this could also be
> caused
> by bad CFI.

Hmm, right. I'm not very familiar with the design philosophy of GDB,
but as far as I have understood it they prefer to rely on producer to 
emit such information. In the LLVM bug report [0] I wrote for this I
mentioned using DW_CFA_undefined for caller-saved registers, or at
least for those that it knows are clobbered.

Neither GCC nor Clang emits CFI for caller-saved registers at the
moment. I have not been successful in finding out why, but my
(uneducated) guess is that, maybe at least one of the reasons, is
debug info size concerns?

[0] https://bugs.llvm.org/show_bug.cgi?id=39752

Best regards,
David
___
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

2018-12-07 Thread David Stenberg via Dwarf-Discuss
On tor, 2018-12-06 at 17:47 -0800, Cary Coutant via Dwarf-Discuss
wrote:
> But we're getting sidetracked from the OP's question: Does GCC in
> fact
> subtract one from the upper bound of a location list entry for a
> variable contained in a caller-saved register? I can think of no
> reason why it should do this. If the compiled code does something
> like
> this:
> 
>     A: promote variable X into caller-save register R
>    ...
>    call f
>     B: ...
>    spill register R back to X
>     C: ...
> 
> The location list entry for x should show it live in register R in
> the
> range [A..C). The call should not interrupt the range.
> 
> It sounds like David has an example where the range list entry shows
> x
> in register R in the range [A..B-1), then presumably again for
> [B..C),
> leaving [B-1..B) uncovered. That would be a bug, in my opinion.
> 
> David, can you show us an example?

In the following example I used GCC 7.3.0, and compiled the below
listed C code using `-O1 -gstrict-dwarf -gdwarf-5'.

  extern int get();
  extern void set(int);
  
  int main() {
    int local = get();
    set(local);
    local = 123;
    return local;
  }

This produces the following location list for `local':

    000c 000e 0014 (DW_OP_reg0 (rax))
0011 0015 001f (DW_OP_const1u: 123;    
                                                DW_OP_stack_value)

   9:   e8 00 00 00 00  callq  e 
   e:   89 c7   mov%eax,%edi
  10:   e8 00 00 00 00  callq  15 
  15:   b8 7b 00 00 00  mov$0x7b,%eax

As seen, there is a one-byte gap at the end of the call instruction to
set().

As far as I have understood it, GCC emits a location list like this
because it knows that the producer will subtract one from the return
address when doing virtual unwinding. In this way, GDB will print the
variable as "" when unwinding from set() to main(), even
though it does not have knowledge of whether or not RAX is caller-
saved.

If we instead use Clang, there is no gap in the location list for the
same code:

    [0x0008, 0x000f): DW_OP_reg0 RAX
[0x000f, 0x0016): DW_OP_consts +123,
  DW_OP_stack_value)

   3:   e8 00 00 00 00  callq  8 
   8:   89 c7   mov%eax,%edi
   a:   e8 00 00 00 00  callq  f 
   f:   b8 7b 00 00 00  mov$0x7b,%eax

When debugging the Clang-built binary in GDB, when unwinding from set()
to main(), `local' will be evaluated using the value RAX has in set(),
rather then being printed as "".

Best regards,
David
___
Dwarf-Discuss mailing list
Dwarf-Discuss@lists.dwarfstd.org
http://lists.dwarfstd.org/listinfo.cgi/dwarf-discuss-dwarfstd.org


[Dwarf-Discuss] Use of Location Description operations in DWARF Expressions?

2020-03-19 Thread David Stenberg via Dwarf-Discuss
Hi!

This is something that has popped up in a number of LLVM patch reviews,
and is something that we would like to get some help with clarifying.

For DWARF[345], may a DWARF Expression (described in section 2.5)
contain any of the operations listed under the Location Descriptions
section (2.6)? For example, may a DW_AT_call_value in DWARF5, which
"is a DWARF expression", contain any of those operations
(e.g. a DW_OP_piece)?

DWARF5 section 2.5 specifies the following for the operations under
section 2.6:

"In addition to the general operations that are defined here, operations
 that are specific to location descriptions are defined in Section 2.6
 on page 38."

Reading section 2.5 and 2.6, I have interpreted the standard as if DWARF
Expressions and Location Descriptions are disparate things; Location
Descriptions may describe locations _using_ DWARF Expressions, but in
places where a DWARF Expression is expected, you may not have a Location
Description in its place. Is that correct?

Given the above quote, and if my interpretation of how DWARF Expressions
and Location Descriptions correlate is correct, I would assume that the
answer to this mail's initial question is no. Or am I overlooking
somethere here?

Best regards,
David
___
Dwarf-Discuss mailing list
Dwarf-Discuss@lists.dwarfstd.org
http://lists.dwarfstd.org/listinfo.cgi/dwarf-discuss-dwarfstd.org


[Dwarf-discuss] Multiple inlined subroutines for a VLIW instruction bundle?

2024-10-17 Thread David Stenberg via Dwarf-discuss
Hi!

Is it possible to encode different backtrace information, including
inlining, for two different instructions in a VLIW bundle?

I'll probably use inprecise and non-standard wording below. Sorry if
that is the case.

Assume that the following C program:

  foo.h:
  static inline void foo_inl_inner() {
__builtin_insn1(); // line 2
  }

  static inline void foo_inl_outer() {
foo_inl_inner(); // line 6
  }

  bar.h:
  static inline void bar_inl() {
__builtin_insn2(); // line 10
  }

  main.c:
  int main() {
foo_inl_outer(); // line 2
bar_inl(); // line 3
  }

where __builtin_#X corresponds to a hardware instruction #X, is
compiled for a VLIW architecture. We may then end up with an VLIW
instruction bundle where insn1 and insn2 are bundled together:

  {
insn1 # foo.h:2
insn2 # bar.h:10
  }

We are able to describe the locations for the two operations in the
instruction bundle by using the op_index register in the line number
program, for example something like this:

AddressLine   Column File   ISA Discriminator OpIndex Flags
-- -- -- -- --- - --- 
0x  2  2  2   0 0   0  is_stmt
0x 10  2  3   0 0   1  is_stmt
[...]

For our proprietary VLIW architecture we have debugging and profiling
tools that are able to indicate which operations in a VLIW bundle that
are of interest, and we would like to query the line information about
those specific operations.

If we do not care about inline subroutines, the use of the op_index
register in the line number program is sufficient for us to query line
and file for the different operations, for example:

  $ debug-tool --no-inlines [PC=...] [op-index=0]
  foo.h:2

  $ debug-tool --no-inlines [PC=...] [op-index=0]
  bar.h:10

However, we would also want to be able to query information about the
two call chains, showing the inlined subroutines, making it easier for
our users to understand from where the operations originate from. For
example:

  $ debug-tool --inlines [PC=...] [op-index=0]
  foo_inl_inner[foo.h:2]
inlined @ foo_inl_outer[foo.h:6]
inlined @ main[main.c:2]

  $ debug-tool --inlines [PC=...] [op-index=1]
  bar_inl[bar.h:10]
inlined @ main[main.c:3]

If I understand correctly, we would somehow need to encode that
information in the "Subroutine and Entry Point Entries" debug
information.

Would a DWARF producer be allowed to emit DW_TAG_subprogram and
concrete DW_TAG_inlined_subroutines entries that describe those two
different call chains for the addresses of that single instruction
bundle?

For example, something like this:

DW_TAG_subprogram
  DW_AT_name "main"
  DW_AT_low_pc 0x0
  DW_AT_high_pc 0x2

  DW_TAG_inlined_subroutine
DW_AT_abstract_origin "foo_inl_outer"
DW_AT_low_pc 0x0
DW_AT_high_pc 0x2

DW_TAG_inlined_subroutine
  DW_AT_abstract_origin "foo_inl_inner"
  DW_AT_low_pc 0x0
  DW_AT_high_pc 0x2

  DW_TAG_inlined_subroutine
DW_AT_abstract_origin "bar_inl"
DW_AT_low_pc 0x0
DW_AT_high_pc 0x2

If that is the case, I do not find anything in the standard that would
help us connect the op_index values to those inlined subroutines. Is
that correct?

Or are there any other way that we could or should model information
about inline subroutines for such VLIW instruction bundles?

The above questions concern how to handle VLIW debug information with
DWARFv5, but I think they may be relevant for non-VLIW architectures
with the Location View Numbering information suggested for DWARFv6
[1], as you may encounter similar situations when merging instructions
coming from different inlined subroutines.

Best regards,
David

[1] https://dwarfstd.org/issues/170427.1.html
-- 
Dwarf-discuss mailing list
Dwarf-discuss@lists.dwarfstd.org
https://lists.dwarfstd.org/mailman/listinfo/dwarf-discuss


Re: [Dwarf-discuss] Multiple inlined subroutines for a VLIW instruction bundle?

2024-10-23 Thread David Stenberg via Dwarf-discuss
On Thu, 2024-10-17 at 12:30 +, John DelSignore wrote:
> 
> Hi,
> 
> I think the best way to encode the information depends on details of
> the processor architecture.

Hi John,

Thanks for the reply, and it's interesting to hear about that Itanium
case!

The scheme that you describe below seems well-suited for such
architectures with fixed-sized, aligned bundles. Unfortunately, for
this particular architecture the distance between consecutive bundles
is not constant, so it is not possible to tell where bundles start or
end just by looking at the address.

> The IA-64 (Intel Itanium architecture) had a VLIW instruction
> encoding with a 128-bit instruction bundle consisting of three 41-bit 
> instruction slots per bundle plus a 5-bit template indicating the
> type of instruction in each slot. Memory was 8-bit byte addressable,
> and an instruction address was encoded as a 128-bit (16-byte) aligned
> bundle address plus a bundle index. So, if the bundle was at address
> 0x56780, the second instruction in the bundle was encoded as 0x56781.
> It's been a long time since I have worked on an IA-64 systems, but I
> believe this convention was used by both the processor and in the
> DWARF. Of course our debugger needed to be modified to handle these
> conventions, but it didn't require anything special the DWARF because
> the bundle address+index convention carried through to all DWARF
> addresses.

A benefit with use of op_index for this architecture is that consumers
can easily retrieve all locations that belong to a bundle by
traversing the line table rows until the address changes. To achieve
the same for this architecture when using the bundle-start-address +
offset scheme, it would then seem like we would need to either somehow
encode where bundles start or end in the debug information (using some
sort of extension?), or let the consumer (or its user) figure out
where bundle boundaries are by looking at disassembled binary output
or some side table containing that information.

If we wish to keep modeling with op_index, and it is not possible to
represent multiple call chains for the same address in the "Subroutine
and Entry Point Entries" debug information, I guess we need to either
find a common shared scope for all the instructions in a bundle, or
use some heuristic that picks the "most relevant" call chain from the
different instructions in the bundle. It would be interesting to
understand how other producers using op_index for a VLIW architecture
or producers emitting the Location View Numbering information for a
non-VLIW architecture have handled that.

> Cheers, John D.

Best regards,
David
-- 
Dwarf-discuss mailing list
Dwarf-discuss@lists.dwarfstd.org
https://lists.dwarfstd.org/mailman/listinfo/dwarf-discuss