Author: Pavel Labath
Date: 2024-10-02T11:13:43+02:00
New Revision: 15f90203bcbc685e8d63a7e52e60adff02bf5499

URL: 
https://github.com/llvm/llvm-project/commit/15f90203bcbc685e8d63a7e52e60adff02bf5499
DIFF: 
https://github.com/llvm/llvm-project/commit/15f90203bcbc685e8d63a7e52e60adff02bf5499.diff

LOG: [lldb/DWARF] Respect member layout for types parsed through declarations 
(#110648)

LLDB code for using the type layout data from DWARF was not kicking in
for types which were initially parsed from a declaration. The problem
was in these lines of code:

```
  if (type)
    layout_info.bit_size = type->GetByteSize(nullptr).value_or(0) * 8;
```

which determine the types layout size by getting the size from the
lldb_private::Type object. The problem is that if the type object does
not have this information cached, this request can trigger another
(recursive) request to lay out/complete the type. This one, somewhat
surprisingly, succeeds, but does that without the type layout
information (because it hasn't been computed yet). The reasons why this
hasn't been noticed so far are:
- this is a relatively new bug. I haven't checked but I suspect it was
introduced in the "delay type definition search" patchset from this
summer -- if we search for the definition eagerly, we will always have a
cached size value.
- it requires the presence of another bug/issue, as otherwise the
automatically computed layout will match the real thing.
- it reproduces (much) more easily with -flimit-debug-info (though it is
possible to trigger it without that flag).

My fix consists of always fetching type size information from DWARF
(which so far existed as a fallback path). I'm not quite sure why this
code was there in the first place (the code goes back to before the
Great LLDB Reformat), but I don't believe it is necessary, as the type
size (for types parsed from definition DIEs) is set exactly from this
attribute (in ParseStructureLikeDIE).

Added: 
    lldb/test/Shell/SymbolFile/DWARF/x86/DW_AT_declaration-unusual-layout.s

Modified: 
    lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
    lldb/test/Shell/SymbolFile/DWARF/x86/DW_AT_declaration-with-children.s

Removed: 
    


################################################################################
diff  --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp 
b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
index 70540fe7fada68..a30d898a93cc4d 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
@@ -2128,14 +2128,10 @@ bool DWARFASTParserClang::CompleteRecordType(const 
DWARFDIE &die,
   TypeSystemClang::BuildIndirectFields(clang_type);
   TypeSystemClang::CompleteTagDeclarationDefinition(clang_type);
 
-  if (type)
-    layout_info.bit_size = type->GetByteSize(nullptr).value_or(0) * 8;
-  if (layout_info.bit_size == 0)
-    layout_info.bit_size =
-        die.GetAttributeValueAsUnsigned(DW_AT_byte_size, 0) * 8;
-  if (layout_info.alignment == 0)
-    layout_info.alignment =
-        die.GetAttributeValueAsUnsigned(llvm::dwarf::DW_AT_alignment, 0) * 8;
+  layout_info.bit_size =
+      die.GetAttributeValueAsUnsigned(DW_AT_byte_size, 0) * 8;
+  layout_info.alignment =
+      die.GetAttributeValueAsUnsigned(llvm::dwarf::DW_AT_alignment, 0) * 8;
 
   clang::CXXRecordDecl *record_decl =
       m_ast.GetAsCXXRecordDecl(clang_type.GetOpaqueQualType());

diff  --git 
a/lldb/test/Shell/SymbolFile/DWARF/x86/DW_AT_declaration-unusual-layout.s 
b/lldb/test/Shell/SymbolFile/DWARF/x86/DW_AT_declaration-unusual-layout.s
new file mode 100644
index 00000000000000..27715c5004720a
--- /dev/null
+++ b/lldb/test/Shell/SymbolFile/DWARF/x86/DW_AT_declaration-unusual-layout.s
@@ -0,0 +1,132 @@
+## Test that lldb respects the layout defined in DWARF even when starting out
+## with a declaration of the class.
+
+# RUN: split-file %s %t
+# RUN: llvm-mc --triple x86_64-pc-linux %t/asm --filetype=obj -o %t.o
+# RUN: %lldb -s %t/commands -o exit %t.o 2>&1 | FileCheck %s
+
+#--- commands
+target var a -fx
+# CHECK-LABEL: target var a
+# CHECK: (A) a = (i = 0xbaadf00d)
+
+#--- asm
+        .data
+        .p2align 4
+        .long 0
+a:
+        .long  0xdeadbeef
+        .long  0xbaadf00d
+
+        .section        .debug_abbrev,"",@progbits
+        .byte   1                               # Abbreviation Code
+        .byte   17                              # DW_TAG_compile_unit
+        .byte   1                               # DW_CHILDREN_yes
+        .byte   37                              # DW_AT_producer
+        .byte   8                               # DW_FORM_string
+        .byte   0                               # EOM(1)
+        .byte   0                               # EOM(2)
+        .byte   2                               # Abbreviation Code
+        .byte   52                              # DW_TAG_variable
+        .byte   0                               # DW_CHILDREN_no
+        .byte   3                               # DW_AT_name
+        .byte   8                               # DW_FORM_string
+        .byte   73                              # DW_AT_type
+        .byte   19                              # DW_FORM_ref4
+        .byte   2                               # DW_AT_location
+        .byte   24                              # DW_FORM_exprloc
+        .byte   0                               # EOM(1)
+        .byte   0                               # EOM(2)
+        .byte   3                               # Abbreviation Code
+        .byte   19                              # DW_TAG_structure_type
+        .byte   0                               # DW_CHILDREN_no
+        .byte   3                               # DW_AT_name
+        .byte   8                               # DW_FORM_string
+        .byte   60                              # DW_AT_declaration
+        .byte   25                              # DW_FORM_flag_present
+        .byte   0                               # EOM(1)
+        .byte   0                               # EOM(2)
+        .byte   4                               # Abbreviation Code
+        .byte   19                              # DW_TAG_structure_type
+        .byte   1                               # DW_CHILDREN_yes
+        .byte   3                               # DW_AT_name
+        .byte   8                               # DW_FORM_string
+        .byte   11                              # DW_AT_byte_size
+        .byte   11                              # DW_FORM_data1
+        .byte   0                               # EOM(1)
+        .byte   0                               # EOM(2)
+        .byte   5                               # Abbreviation Code
+        .byte   13                              # DW_TAG_member
+        .byte   0                               # DW_CHILDREN_no
+        .byte   3                               # DW_AT_name
+        .byte   8                               # DW_FORM_string
+        .byte   73                              # DW_AT_type
+        .byte   19                              # DW_FORM_ref4
+        .byte   56                              # DW_AT_data_member_location
+        .byte   11                              # DW_FORM_data1
+        .byte   0                               # EOM(1)
+        .byte   0                               # EOM(2)
+        .byte   6                               # Abbreviation Code
+        .byte   36                              # DW_TAG_base_type
+        .byte   0                               # DW_CHILDREN_no
+        .byte   3                               # DW_AT_name
+        .byte   8                               # DW_FORM_string
+        .byte   62                              # DW_AT_encoding
+        .byte   11                              # DW_FORM_data1
+        .byte   11                              # DW_AT_byte_size
+        .byte   11                              # DW_FORM_data1
+        .byte   0                               # EOM(1)
+        .byte   0                               # EOM(2)
+        .byte   0                               # EOM(3)
+
+        .section        .debug_info,"",@progbits
+.Lcu_begin0:
+        .long   .Ldebug_info_end0-.Ldebug_info_start0 # Length of Unit
+.Ldebug_info_start0:
+        .short  4                               # DWARF version number
+        .long   .debug_abbrev                   # Offset Into Abbrev. Section
+        .byte   8                               # Address Size (in bytes)
+        .byte   1                               # Abbrev [1] 
DW_TAG_compile_unit
+        .asciz  "Hand-written DWARF"            # DW_AT_producer
+
+        .byte   2                               # Abbrev [2] DW_TAG_variable
+        .asciz  "a"                             # DW_AT_name
+        .long   .LA_decl-.Lcu_begin0            # DW_AT_type
+        .byte   9                               # DW_AT_location
+        .byte   3
+        .quad   a
+.LA_decl:
+        .byte   3                               # Abbrev [3] 
DW_TAG_structure_type
+        .asciz  "A"                             # DW_AT_name
+                                                # DW_AT_declaration
+        .byte   0                               # End Of Children Mark
+.Ldebug_info_end0:
+
+.Lcu_begin1:
+        .long   .Ldebug_info_end1-.Ldebug_info_start1 # Length of Unit
+.Ldebug_info_start1:
+        .short  4                               # DWARF version number
+        .long   .debug_abbrev                   # Offset Into Abbrev. Section
+        .byte   8                               # Address Size (in bytes)
+        .byte   1                               # Abbrev [1] 
DW_TAG_compile_unit
+        .asciz  "Hand-written DWARF"            # DW_AT_producer
+
+        .byte   4                               # Abbrev [4] 
DW_TAG_structure_type
+        .asciz  "A"                             # DW_AT_name
+                                                # DW_AT_declaration
+        .byte   8                               # DW_AT_byte_size
+        .byte   5                               # Abbrev [5] DW_TAG_member
+        .asciz  "i"                             # DW_AT_name
+        .long   .Lint-.Lcu_begin1               # DW_AT_type
+## NB: empty padding before this member
+        .byte   4                               # DW_AT_data_member_location
+        .byte   0                               # End Of Children Mark
+
+.Lint:
+        .byte   6                               # Abbrev [6] DW_TAG_base_type
+        .asciz  "int"                           # DW_AT_name
+        .byte   5                               # DW_AT_encoding
+        .byte   4                               # DW_AT_byte_size
+
+        .byte   0                               # End Of Children Mark
+.Ldebug_info_end1:

diff  --git 
a/lldb/test/Shell/SymbolFile/DWARF/x86/DW_AT_declaration-with-children.s 
b/lldb/test/Shell/SymbolFile/DWARF/x86/DW_AT_declaration-with-children.s
index 8633d02f492e67..16bdbd3cfaad6e 100644
--- a/lldb/test/Shell/SymbolFile/DWARF/x86/DW_AT_declaration-with-children.s
+++ b/lldb/test/Shell/SymbolFile/DWARF/x86/DW_AT_declaration-with-children.s
@@ -105,6 +105,8 @@ c1:
         .byte   1                               # DW_CHILDREN_yes
         .byte   3                               # DW_AT_name
         .byte   8                               # DW_FORM_string
+        .byte   11                              # DW_AT_byte_size
+        .byte   11                              # DW_FORM_data1
         .byte   0                               # EOM(1)
         .byte   0                               # EOM(2)
         .byte   7                               # Abbreviation Code
@@ -251,6 +253,7 @@ c1:
 .LB1:
         .byte   6                               # Abbrev [6] DW_TAG_class_type
         .asciz  "B1"                            # DW_AT_name
+        .byte   8                               # DW_AT_byte_size
         .byte   7                               # Abbrev [5] 0x58:0xc 
DW_TAG_member
         .asciz  "ptr"                           # DW_AT_name
         .long   .LAptr                          # DW_AT_type


        
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to