<div dir="ltr"><div dir="ltr"><br></div><br><div class="gmail_quote gmail_quote_container"><div dir="ltr" class="gmail_attr">On Wed, Jan 14, 2026 at 7:44 PM Y Song <<a href="mailto:ys114321@gmail.com">ys114321@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">Thanks. Now let us say I will not try to add those "changed function<br>
signatures" to dwarf<br>
and actually rely on dwarf locations to somehow recover parameters.</blockquote><div><br></div><div>That isn't possible, so far as I can see - DWARF only describes how to access the parameters from inside the function, not how they were passed on the call. (eg: an unoptimized build will probably describe the parameters as being in stack memory even though the values were passed in registers - because the prologue moves the values from registers to memory, and the DWARF locations only have to be valid after the prologue)</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"> I understand<br>
in some cases, it is not easy to recover if dwarf locations are too<br>
complicated and we<br>
might ignore those cases.<br>
<br>
I actually want to ask how to identify whether the return type is<br>
changed or not in dwarf.<br>
The following is an example:<br>
<br>
$ cat test.c<br>
#include <stdio.h><br>
unsigned tar(int a);<br>
__attribute__((noinline)) static int foo(int a, int b)<br>
{<br>
return tar(a) + tar(a + 1);<br>
}<br>
__attribute__((noinline)) int bar(int a)<br>
{<br>
foo(a, 1);<br>
return 0;<br>
}<br>
<br>
In this particular case, the return value of foo() is actually not used<br>
and the compiler will optimize it away with returning void in llvm.<br></blockquote><div><br><a href="https://dwarfstd.org/issues/221105.1.html">https://dwarfstd.org/issues/221105.1.html</a> in DWARFv6 might help provide some of this information & is closer to an ABI-encoding than we have for parameters.<br> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<br>
$ clang -O2 -g -c test.c<br>
$ llvm-dwarfdump test.o<br>
...<br>
0x0000004e: DW_TAG_subprogram<br>
DW_AT_low_pc (0x0000000000000010)<br>
DW_AT_high_pc (0x0000000000000022)<br>
DW_AT_frame_base (DW_OP_reg7 RSP)<br>
DW_AT_call_all_calls (true)<br>
DW_AT_name ("foo")<br>
DW_AT_decl_file ("/home/yhs/tests/sig-change/deadret/test.c")<br>
DW_AT_decl_line (3)<br>
DW_AT_prototyped (true)<br>
DW_AT_calling_convention (DW_CC_nocall)<br>
DW_AT_type (0x00000096 "int")<br>
<br>
0x0000005e: DW_TAG_formal_parameter<br>
DW_AT_location (indexed (0x1) loclist = 0x00000022:<br>
[0x0000000000000010, 0x0000000000000018): DW_OP_reg5 RDI<br>
[0x0000000000000018, 0x000000000000001a): DW_OP_reg3 RBX<br>
[0x000000000000001a, 0x0000000000000022):<br>
DW_OP_entry_value(DW_OP_reg5 RDI), DW_OP_stack_value)<br>
DW_AT_name ("a")<br>
DW_AT_decl_file<br>
("/home/yhs/tests/sig-change/deadret/test.c")<br>
DW_AT_decl_line (3)<br>
DW_AT_type (0x00000096 "int")<br>
<br>
0x00000067: DW_TAG_formal_parameter<br>
DW_AT_name ("b")<br>
DW_AT_decl_file<br>
("/home/yhs/tests/sig-change/deadret/test.c")<br>
DW_AT_decl_line (3)<br>
DW_AT_type (0x00000096 "int")<br>
...<br>
Assembly code:<br>
0000000000000000 <bar>:<br>
0: 50 pushq %rax<br>
1: e8 0a 00 00 00 callq 0x10 <foo><br>
6: 31 c0 xorl %eax, %eax<br>
8: 59 popq %rcx<br>
9: c3 retq<br>
a: 66 0f 1f 44 00 00 nopw (%rax,%rax)<br>
<br>
0000000000000010 <foo>:<br>
10: 53 pushq %rbx<br>
11: 89 fb movl %edi, %ebx<br>
13: e8 00 00 00 00 callq 0x18 <foo+0x8><br>
18: ff c3 incl %ebx<br>
1a: 89 df movl %ebx, %edi<br>
1c: 5b popq %rbx<br>
1d: e9 00 00 00 00 jmp 0x22 <foo+0x12><br>
<br>
The compiler knows whether the return type has changed or not.<br>
Unfortunately the information is not available in dwarf.<br>
<br>
Any suggestions to add some additional information in dwarf so we can<br>
find whether the return type is changed or not?<br>
</blockquote></div></div>