llvm / llvm-project

The LLVM Project is a collection of modular and reusable compiler and toolchain technologies.
http://llvm.org
Other
28.15k stars 11.62k forks source link

debug_info missing parameters for naked functions #38172

Open c1ed623a-df99-497b-81ca-bca6dae737a4 opened 6 years ago

c1ed623a-df99-497b-81ca-bca6dae737a4 commented 6 years ago
Bugzilla Link 38824
Version trunk
OS Linux
Attachments source file
CC @adrian-prantl,@dwblaikie,@JDevlieghere,@pogo59,@rnk

Extended Description

Source file:

extern "C" void naked_function(int value, char name); extern "C" void regular_function(int value, char name);

void attribute((naked, noinline)) naked_function(int value, char* name) { }

void regular_function(int value, char* name) { }

Command line: clang++ -g --shared -fPIC -o libtest.so src.cc

Result: $ readelf -wi libtest.so Contents of the .debug_info section:

Compilation Unit @ offset 0x0: Length: 0x81 (32-bit) Version: 4 Abbrev Offset: 0x0 Pointer Size: 8

<0>: Abbrev Number: 1 (DW_TAG_compile_unit) DW_AT_producer : (indirect string, offset: 0x0): clang version 8.0.0 (https://git.llvm.org/git/clang.git/ 1bc73590ad1335313e8f262393547b8af67c9167) (https://git.llvm.org/git/llvm.git/ 24a8df2c420ee959f27acae6bac2969cdd0a5388) <10> DW_AT_language : 4 (C++) <12> DW_AT_name : (indirect string, offset: 0xb1): src.cc <16> DW_AT_stmt_list : 0x0 <1a> DW_AT_comp_dir : (indirect string, offset: 0xb8): /ssd/llvm/test/naked_debug_info <1e> DW_AT_low_pc : 0x610 <26> DW_AT_high_pc : 0x1d <1><2a>: Abbrev Number: 2 (DW_TAG_subprogram) <2b> DW_AT_low_pc : 0x610 <33> DW_AT_high_pc : 0x7 <37> DW_AT_frame_base : 1 byte block: 56 (DW_OP_reg6 (rbp)) <39> DW_AT_name : (indirect string, offset: 0xd8): naked_function <3d> DW_AT_decl_file : 1 <3e> DW_AT_decl_line : 4 <3f> DW_AT_external : 1 <1><3f>: Abbrev Number: 3 (DW_TAG_subprogram) <40> DW_AT_low_pc : 0x620 <48> DW_AT_high_pc : 0xd <4c> DW_AT_frame_base : 1 byte block: 56 (DW_OP_reg6 (rbp)) <4e> DW_AT_name : (indirect string, offset: 0xe7): regular_function <52> DW_AT_decl_file : 1 <53> DW_AT_decl_line : 7 <54> DW_AT_external : 1 <2><54>: Abbrev Number: 4 (DW_TAG_formal_parameter) <55> DW_AT_location : 2 byte block: 91 7c (DW_OP_fbreg: -4) <58> DW_AT_name : (indirect string, offset: 0xf8): value <5c> DW_AT_decl_file : 1 <5d> DW_AT_decl_line : 7 <5e> DW_AT_type : <0x71> <2><62>: Abbrev Number: 4 (DW_TAG_formal_parameter) <63> DW_AT_location : 2 byte block: 91 70 (DW_OP_fbreg: -16) <66> DW_AT_name : (indirect string, offset: 0x102): name <6a> DW_AT_decl_file : 1 <6b> DW_AT_decl_line : 7 <6c> DW_AT_type : <0x78> <2><70>: Abbrev Number: 0 <1><71>: Abbrev Number: 5 (DW_TAG_base_type) <72> DW_AT_name : (indirect string, offset: 0xfe): int <76> DW_AT_encoding : 5 (signed) <77> DW_AT_byte_size : 4 <1><78>: Abbrev Number: 6 (DW_TAG_pointer_type) <79> DW_AT_type : <0x7d> <1><7d>: Abbrev Number: 5 (DW_TAG_base_type) <7e> DW_AT_name : (indirect string, offset: 0x107): char <82> DW_AT_encoding : 6 (signed char) <83> DW_AT_byte_size : 1 <1><84>: Abbrev Number: 0 Note that while parameters for not naked function are preserved naked function parameters are lost.
dwblaikie commented 6 years ago

What Reid said sounds about right.

Another thing we could do/check is that the parameter DILocalVariables end up in the "retainedNodes" list associated with the DISubprogram. So the function type is correct even if no locations are identified inside the function.

rnk commented 6 years ago

We emit debug info for parameters during CodeGenFunction::EmitFunctionProlog, and marking a function naked prevents prologue emission, as expected.

To fix it, we'd need to emit llvm.dbg.value intrinsics instead of llvm.dbg.declare intrinsics, since all we have are SSA registers to talk about, no allocas. We'd need to call DIBuilder::insertDbgValueIntrinsic.