Quuxplusone / LLVMBugzillaTest

0 stars 0 forks source link

debug_info missing parameters for naked functions #37797

Open Quuxplusone opened 6 years ago

Quuxplusone commented 6 years ago
Bugzilla Link PR38824
Status NEW
Importance P enhancement
Reported by dimitry (dimitry@google.com)
Reported on 2018-09-04 07:23:00 -0700
Last modified on 2018-09-04 12:03:27 -0700
Version trunk
Hardware PC Linux
CC aprantl@apple.com, dblaikie@gmail.com, jdevlieghere@apple.com, llvm-bugs@lists.llvm.org, paul_robinson@playstation.sony.com, rnk@google.com
Fixed by commit(s)
Attachments src.cc (243 bytes, text/x-c++src)
Blocks
Blocked by
See also
Created attachment 20837
source file

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><b>: Abbrev Number: 1 (DW_TAG_compile_unit)
    <c>   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.
Quuxplusone commented 6 years ago

Attached src.cc (243 bytes, text/x-c++src): source file

Quuxplusone 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.

Quuxplusone 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.