You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
[LLVM] Emit dwarf data for changed-signature and new functions
Add a new pass EmitChangedFuncDebugInfo which will add dwarf for
additional functions including functions with signature change
and new functions.
The previous approach in [1] tries to add debuginfo for those
optimization passes which cause signature changes. Based on
discussion in [1], it is preferred to have a specific pass to
add debuginfo and later on dwarf generation can include those
new debuginfo.
The ultimate goal is to add new information to dwarf like below:
DW_TAG_compile_unit
...
// New functions with suffix
DW_TAG_inlined_subroutine
DW_AT_name ("foo.1")
DW_AT_type (0x0000000000000091 "int")
DW_AT_artificial (true)
DW_AT_specificiation (original DW_TAG_subprogram)
DW_TAG_formal_parameter
DW_AT_name ("b")
DW_AT_type (0x0000000000000091 "int")
DW_TAG_formal_parameter
DW_AT_name ("c")
DW_AT_type (0x0000000000000095 "long")
...
// Functions with changed signatures
DW_TAG_inlined_subroutine
DW_AT_name ("bar")
DW_AT_type (0x0000000000000091 "int")
DW_AT_artificial (true)
DW_AT_specificiation (original DW_TAG_subprogram)
DW_TAG_formal_parameter
DW_AT_name ("c")
DW_AT_type (0x0000000000000095 "unsigned int")
...
// Functions not obtained function changed signatures yet
// The DW_CC_nocall presence indicates such cases.
DW_TAG_inlined_subroutine
DW_AT_name ("bar" or "bar.1")
DW_AT_calling_convention (DW_CC_nocall)
DW_AT_artificial (true)
DW_AT_specificiation (original DW_TAG_subprogram)
The parent tag of above DW_TAG_inlined_subroutine is
DW_TAG_compile_unit. This is a new feature for dwarf
so it won't cause issues with existing dwarf related tools.
Total three patterns are introduced as the above.
. New functions with suffix, e.g., 'foo.1' or 'foo.llvm.<hash>'.
. Functions with changed signature due to ArgumentPromotion
or DeadArgumentElimination.
. Functions the current implementation cannot get proper
signature. For this case, DW_CC_nocall is set to indicate
signature is lost. More details in the below.
A special CompileUnit with file name "<artificial>" is created
to hold special DISubprograms for the above three kinds of functions.
During actual dwarf generation, these special DISubprograms
will turn to above to proper DW_TAG_inlined_subroutine tags.
The below are some discussions with not handled cases and
some other alternative things:
(1) Currently, there are three not handled signature changes.
. During to ArgumentPromotion, we may have
foo(..., struct foo *p, ...) => foo(..., int p.0.val, int p.4.val, ...)
. Struct argument which expands to two actual arguments,
foo(..., struct foo v, ...) => foo(..., v.coerce0, v.coerce1, ...)
. Struct argument changed to struct pointer,
foo(..., struct foo v, ...) => foo(..., struct foo *p, ...)
I think by utilizing dbg_value/dbg_declare and instructions, we
might be able to resolve the above and get proper signature.
But any suggestions are welcome.
(2) Currently, I am using a special CompileUnit "<artificial>" to hold
newly created DISubprograms. But there is an alternative.
For example, "llvm.dbg.cu" metadata is used to hold all CompileUnits.
We could introduce "llvm.dbg.sp.extra" to hold all new
DISubprograms instead of a new CompileUnit.
I have tested this patch set by building latest bpf-next linux kernel.
For no-lto case:
65288 original number of functions
910 new functions with this patch (including DW_CC_nocall case)
7 new functions without signatures (with DW_CC_nocall)
For thin-lto case:
65541 original number of functions
2324 new functions with this patch (including DW_CC_nocall case)
14 new functions without signatures (with DW_CC_nocall)
The following are some examples with thinlto with generated dwarf:
...
0x0001707f: DW_TAG_inlined_subroutine
DW_AT_name ("msr_build_context")
DW_AT_type (0x00004163 "int")
DW_AT_artificial (true)
DW_AT_specification (0x0000440b "msr_build_context")
0x0001708b: DW_TAG_formal_parameter
DW_AT_name ("msr_id")
DW_AT_type (0x0000e55c "const u32 *")
0x00017093: NULL
...
0x004225e5: DW_TAG_inlined_subroutine
DW_AT_name ("__die_body.llvm.14794269134614576759")
DW_AT_type (0x00418a14 "int")
DW_AT_artificial (true)
DW_AT_specification (0x00422348 "__die_body")
0x004225f1: DW_TAG_formal_parameter
DW_AT_name ("")
DW_AT_type (0x004181f3 "const char *")
0x004225f9: DW_TAG_formal_parameter
DW_AT_name ("")
DW_AT_type (0x00419118 "pt_regs *")
0x00422601: DW_TAG_formal_parameter
DW_AT_name ("")
DW_AT_type (0x0041af2f "long")
0x00422609: NULL
...
0x013f5dac: DW_TAG_inlined_subroutine
DW_AT_name ("devkmsg_emit")
DW_AT_calling_convention (DW_CC_nocall)
DW_AT_artificial (true)
DW_AT_specification (0x013ef75b "devkmsg_emit")
[1] #127855
0 commit comments