Skip to content

Commit 9e55aed

Browse files
mhaselvolsa
andauthored
fix: DebugInfo alignment and offset for aggregate types (#1329)
Arrays and Strings now use the inner type to calculate running-offset and alignment. Offsets and sizes now align with a comparable `C` program compiled with clang: ```c #include <stdbool.h> typedef struct { short a; bool b; char s[81]; long long ll; short arr[11]; short j; } mainProg_t; int main() { return 0; } ``` generated DI: ```llvm !14 = !DIDerivedType(tag: DW_TAG_typedef, name: "mainProg_t", file: !1, line: 10, baseType: !15) !15 = distinct !DICompositeType(tag: DW_TAG_structure_type, file: !1, line: 3, size: 960, elements: !16) !16 = !{!17, !19, !21, !26, !28, !32} !17 = !DIDerivedType(tag: DW_TAG_member, name: "a", scope: !15, file: !1, line: 4, baseType: !18, size: 16) !18 = !DIBasicType(name: "short", size: 16, encoding: DW_ATE_signed) !19 = !DIDerivedType(tag: DW_TAG_member, name: "b", scope: !15, file: !1, line: 5, baseType: !20, size: 8, offset: 16) !20 = !DIBasicType(name: "_Bool", size: 8, encoding: DW_ATE_boolean) !21 = !DIDerivedType(tag: DW_TAG_member, name: "s", scope: !15, file: !1, line: 6, baseType: !22, size: 648, offset: 24) !22 = !DICompositeType(tag: DW_TAG_array_type, baseType: !23, size: 648, elements: !24) !23 = !DIBasicType(name: "char", size: 8, encoding: DW_ATE_signed_char) !24 = !{!25} !25 = !DISubrange(count: 81) !26 = !DIDerivedType(tag: DW_TAG_member, name: "ll", scope: !15, file: !1, line: 7, baseType: !27, size: 64, offset: 704) !27 = !DIBasicType(name: "long long", size: 64, encoding: DW_ATE_signed) !28 = !DIDerivedType(tag: DW_TAG_member, name: "arr", scope: !15, file: !1, line: 8, baseType: !29, size: 176, offset: 768) !29 = !DICompositeType(tag: DW_TAG_array_type, baseType: !18, size: 176, elements: !30) !30 = !{!31} !31 = !DISubrange(count: 11) !32 = !DIDerivedType(tag: DW_TAG_member, name: "j", scope: !15, file: !1, line: 9, baseType: !18, size: 16, offset: 944) ``` ```llvm PROGRAM prog VAR a : INT := 420; b : BOOL := TRUE; s : STRING := 'Hello, world!'; ll : LINT := 69; arr : ARRAY[0..10] OF INT; j : INT; END_VAR END_PROGRAM FUNCTION main : DINT END_FUNCTION ``` generated DI: ```llvm !3 = !DICompositeType(tag: DW_TAG_structure_type, name: "prog", scope: !2, file: !2, line: 11, size: 960, align: 64, flags: DIFlagPublic, elements: !4, identifier: "prog") !4 = !{!5, !7, !9, !14, !16, !20} !5 = !DIDerivedType(tag: DW_TAG_member, name: "a", scope: !2, file: !2, line: 13, baseType: !6, size: 16, align: 16, flags: DIFlagPublic) !6 = !DIBasicType(name: "INT", size: 16, encoding: DW_ATE_signed, flags: DIFlagPublic) !7 = !DIDerivedType(tag: DW_TAG_member, name: "b", scope: !2, file: !2, line: 14, baseType: !8, size: 8, align: 8, offset: 16, flags: DIFlagPublic) !8 = !DIBasicType(name: "BOOL", size: 8, encoding: DW_ATE_boolean, flags: DIFlagPublic) !9 = !DIDerivedType(tag: DW_TAG_member, name: "s", scope: !2, file: !2, line: 15, baseType: !10, size: 648, align: 8, offset: 24, flags: DIFlagPublic) !10 = !DICompositeType(tag: DW_TAG_array_type, baseType: !11, size: 648, align: 8, elements: !12) !11 = !DIBasicType(name: "char", size: 8, encoding: DW_ATE_UTF, flags: DIFlagPublic) !12 = !{!13} !13 = !DISubrange(count: 81, lowerBound: 0) !14 = !DIDerivedType(tag: DW_TAG_member, name: "ll", scope: !2, file: !2, line: 16, baseType: !15, size: 64, align: 64, offset: 704, flags: DIFlagPublic) !15 = !DIBasicType(name: "LINT", size: 64, encoding: DW_ATE_signed, flags: DIFlagPublic) !16 = !DIDerivedType(tag: DW_TAG_member, name: "arr", scope: !2, file: !2, line: 17, baseType: !17, size: 176, align: 16, offset: 768, flags: DIFlagPublic) !17 = !DICompositeType(tag: DW_TAG_array_type, baseType: !6, size: 176, align: 16, elements: !18) !18 = !{!19} !19 = !DISubrange(count: 11, lowerBound: 0) !20 = !DIDerivedType(tag: DW_TAG_member, name: "j", scope: !2, file: !2, line: 18, baseType: !6, size: 16, align: 16, offset: 944, flags: DIFlagPublic) ``` Running an example program with the above struct with initialized values now also prints the expected values when running `info locals` in gdb. ![image](https://github.com/user-attachments/assets/ae328259-1c4f-4c77-97b1-78963e69eafc) --------- Co-authored-by: Volkan Sagcan <Volkan.SAGCAN@bachmann.info>
1 parent 1bb47b7 commit 9e55aed

8 files changed

+23
-24
lines changed

src/codegen/tests/debug_tests/snapshots/rusty__codegen__tests__debug_tests__expression_debugging__aggregate_return_value_variable_in_function.snap

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ attributes #2 = { argmemonly nofree nounwind willreturn }
4949
!9 = !DILocation(line: 3, column: 12, scope: !4)
5050
!10 = !DILocalVariable(name: "myFunc", scope: !4, file: !5, line: 2, type: !11)
5151
!11 = !DIDerivedType(tag: DW_TAG_pointer_type, name: "__ref_to_STRING", baseType: !12, size: 64, align: 64, dwarfAddressSpace: 1)
52-
!12 = !DICompositeType(tag: DW_TAG_array_type, baseType: !13, size: 80, align: 64, elements: !14)
52+
!12 = !DICompositeType(tag: DW_TAG_array_type, baseType: !13, size: 648, align: 8, elements: !14)
5353
!13 = !DIBasicType(name: "char", size: 8, encoding: DW_ATE_UTF, flags: DIFlagPublic)
5454
!14 = !{!15}
5555
!15 = !DISubrange(count: 81, lowerBound: 0)

src/codegen/tests/debug_tests/snapshots/rusty__codegen__tests__debug_tests__expression_debugging__array_size_correctly_set_in_dwarf_info.snap

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,8 @@ attributes #1 = { argmemonly nofree nounwind willreturn writeonly }
4040
!7 = !{null}
4141
!8 = !{}
4242
!9 = !DILocation(line: 6, column: 8, scope: !4)
43-
!10 = !DILocalVariable(name: "a", scope: !4, file: !5, line: 4, type: !11, align: 64)
44-
!11 = !DICompositeType(tag: DW_TAG_array_type, baseType: !12, size: 2048, align: 64, elements: !13)
43+
!10 = !DILocalVariable(name: "a", scope: !4, file: !5, line: 4, type: !11, align: 32)
44+
!11 = !DICompositeType(tag: DW_TAG_array_type, baseType: !12, size: 2048, align: 32, elements: !13)
4545
!12 = !DIBasicType(name: "DINT", size: 32, encoding: DW_ATE_signed, flags: DIFlagPublic)
4646
!13 = !{!14}
4747
!14 = !DISubrange(count: 64, lowerBound: 1)

src/codegen/tests/debug_tests/snapshots/rusty__codegen__tests__debug_tests__expression_debugging__string_size_correctly_set_in_dwarf_info.snap

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ source_filename = "<internal>"
1313
!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression())
1414
!1 = distinct !DIGlobalVariable(name: "a", scope: !2, file: !2, line: 3, type: !3, isLocal: false, isDefinition: true)
1515
!2 = !DIFile(filename: "<internal>", directory: "")
16-
!3 = !DICompositeType(tag: DW_TAG_array_type, baseType: !4, size: 64, align: 64, elements: !5)
16+
!3 = !DICompositeType(tag: DW_TAG_array_type, baseType: !4, size: 520, align: 8, elements: !5)
1717
!4 = !DIBasicType(name: "char", size: 8, encoding: DW_ATE_UTF, flags: DIFlagPublic)
1818
!5 = !{!6}
1919
!6 = !DISubrange(count: 65, lowerBound: 0)

src/codegen/tests/snapshots/rusty__codegen__tests__debug_tests__global_var_array_added_to_debug_info.snap

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,19 +15,19 @@ source_filename = "<internal>"
1515
!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression())
1616
!1 = distinct !DIGlobalVariable(name: "a", scope: !2, file: !2, line: 3, type: !3, isLocal: false, isDefinition: true)
1717
!2 = !DIFile(filename: "<internal>", directory: "")
18-
!3 = !DICompositeType(tag: DW_TAG_array_type, baseType: !4, size: 352, align: 64, elements: !5)
18+
!3 = !DICompositeType(tag: DW_TAG_array_type, baseType: !4, size: 352, align: 32, elements: !5)
1919
!4 = !DIBasicType(name: "DINT", size: 32, encoding: DW_ATE_signed, flags: DIFlagPublic)
2020
!5 = !{!6}
2121
!6 = !DISubrange(count: 11, lowerBound: 0)
2222
!7 = !DIGlobalVariableExpression(var: !8, expr: !DIExpression())
2323
!8 = distinct !DIGlobalVariable(name: "b", scope: !2, file: !2, line: 4, type: !9, isLocal: false, isDefinition: true)
24-
!9 = !DICompositeType(tag: DW_TAG_array_type, baseType: !4, size: 3520, align: 64, elements: !10)
24+
!9 = !DICompositeType(tag: DW_TAG_array_type, baseType: !4, size: 3520, align: 32, elements: !10)
2525
!10 = !{!6, !11}
2626
!11 = !DISubrange(count: 10, lowerBound: 11)
2727
!12 = !DIGlobalVariableExpression(var: !13, expr: !DIExpression())
2828
!13 = distinct !DIGlobalVariable(name: "c", scope: !2, file: !2, line: 5, type: !14, isLocal: false, isDefinition: true)
29-
!14 = !DICompositeType(tag: DW_TAG_array_type, baseType: !15, size: 3520, align: 64, elements: !5)
30-
!15 = !DICompositeType(tag: DW_TAG_array_type, baseType: !4, size: 320, align: 64, elements: !16)
29+
!14 = !DICompositeType(tag: DW_TAG_array_type, baseType: !15, size: 3520, align: 32, elements: !5)
30+
!15 = !DICompositeType(tag: DW_TAG_array_type, baseType: !4, size: 320, align: 32, elements: !16)
3131
!16 = !{!11}
3232
!17 = !{i32 2, !"Dwarf Version", i32 5}
3333
!18 = !{i32 2, !"Debug Info Version", i32 3}

src/codegen/tests/snapshots/rusty__codegen__tests__debug_tests__global_var_string_added_to_debug_info.snap

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,13 @@ source_filename = "<internal>"
1414
!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression())
1515
!1 = distinct !DIGlobalVariable(name: "a", scope: !2, file: !2, line: 3, type: !3, isLocal: false, isDefinition: true)
1616
!2 = !DIFile(filename: "<internal>", directory: "")
17-
!3 = !DICompositeType(tag: DW_TAG_array_type, baseType: !4, size: 80, align: 64, elements: !5)
17+
!3 = !DICompositeType(tag: DW_TAG_array_type, baseType: !4, size: 648, align: 8, elements: !5)
1818
!4 = !DIBasicType(name: "char", size: 8, encoding: DW_ATE_UTF, flags: DIFlagPublic)
1919
!5 = !{!6}
2020
!6 = !DISubrange(count: 81, lowerBound: 0)
2121
!7 = !DIGlobalVariableExpression(var: !8, expr: !DIExpression())
2222
!8 = distinct !DIGlobalVariable(name: "b", scope: !2, file: !2, line: 4, type: !9, isLocal: false, isDefinition: true)
23-
!9 = !DICompositeType(tag: DW_TAG_array_type, baseType: !10, size: 160, align: 64, elements: !5)
23+
!9 = !DICompositeType(tag: DW_TAG_array_type, baseType: !10, size: 1296, align: 16, elements: !5)
2424
!10 = !DIBasicType(name: "wchar", size: 16, encoding: DW_ATE_UTF, flags: DIFlagPublic)
2525
!11 = !{i32 2, !"Dwarf Version", i32 5}
2626
!12 = !{i32 2, !"Debug Info Version", i32 3}

src/codegen/tests/snapshots/rusty__codegen__tests__debug_tests__global_var_struct_added_to_debug_info.snap

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,8 @@ source_filename = "<internal>"
2323
!6 = !DIBasicType(name: "DINT", size: 32, encoding: DW_ATE_signed, flags: DIFlagPublic)
2424
!7 = !DIDerivedType(tag: DW_TAG_member, name: "b", scope: !2, file: !2, line: 4, baseType: !8, size: 64, align: 64, offset: 64, flags: DIFlagPublic)
2525
!8 = !DIBasicType(name: "LREAL", size: 64, encoding: DW_ATE_float, flags: DIFlagPublic)
26-
!9 = !DIDerivedType(tag: DW_TAG_member, name: "c", scope: !2, file: !2, line: 5, baseType: !10, size: 352, align: 64, offset: 128, flags: DIFlagPublic)
27-
!10 = !DICompositeType(tag: DW_TAG_array_type, baseType: !6, size: 352, align: 64, elements: !11)
26+
!9 = !DIDerivedType(tag: DW_TAG_member, name: "c", scope: !2, file: !2, line: 5, baseType: !10, size: 352, align: 32, offset: 128, flags: DIFlagPublic)
27+
!10 = !DICompositeType(tag: DW_TAG_array_type, baseType: !6, size: 352, align: 32, elements: !11)
2828
!11 = !{!12}
2929
!12 = !DISubrange(count: 11, lowerBound: 0)
3030
!13 = !DIGlobalVariableExpression(var: !14, expr: !DIExpression())
@@ -69,8 +69,8 @@ attributes #0 = { nofree nosync nounwind readnone speculatable willreturn }
6969
!6 = !DIBasicType(name: "DINT", size: 32, encoding: DW_ATE_signed, flags: DIFlagPublic)
7070
!7 = !DIDerivedType(tag: DW_TAG_member, name: "b", scope: !2, file: !2, line: 4, baseType: !8, size: 64, align: 64, offset: 64, flags: DIFlagPublic)
7171
!8 = !DIBasicType(name: "LREAL", size: 64, encoding: DW_ATE_float, flags: DIFlagPublic)
72-
!9 = !DIDerivedType(tag: DW_TAG_member, name: "c", scope: !2, file: !2, line: 5, baseType: !10, size: 352, align: 64, offset: 128, flags: DIFlagPublic)
73-
!10 = !DICompositeType(tag: DW_TAG_array_type, baseType: !6, size: 352, align: 64, elements: !11)
72+
!9 = !DIDerivedType(tag: DW_TAG_member, name: "c", scope: !2, file: !2, line: 5, baseType: !10, size: 352, align: 32, offset: 128, flags: DIFlagPublic)
73+
!10 = !DICompositeType(tag: DW_TAG_array_type, baseType: !6, size: 352, align: 32, elements: !11)
7474
!11 = !{!12}
7575
!12 = !DISubrange(count: 11, lowerBound: 0)
7676
!13 = !{i32 2, !"Dwarf Version", i32 5}
@@ -114,8 +114,8 @@ declare !dbg !25 void @__init_mystruct(%myStruct*)
114114
!6 = !DIBasicType(name: "DINT", size: 32, encoding: DW_ATE_signed, flags: DIFlagPublic)
115115
!7 = !DIDerivedType(tag: DW_TAG_member, name: "b", scope: !2, file: !2, line: 4, baseType: !8, size: 64, align: 64, offset: 64, flags: DIFlagPublic)
116116
!8 = !DIBasicType(name: "LREAL", size: 64, encoding: DW_ATE_float, flags: DIFlagPublic)
117-
!9 = !DIDerivedType(tag: DW_TAG_member, name: "c", scope: !2, file: !2, line: 5, baseType: !10, size: 352, align: 64, offset: 128, flags: DIFlagPublic)
118-
!10 = !DICompositeType(tag: DW_TAG_array_type, baseType: !6, size: 352, align: 64, elements: !11)
117+
!9 = !DIDerivedType(tag: DW_TAG_member, name: "c", scope: !2, file: !2, line: 5, baseType: !10, size: 352, align: 32, offset: 128, flags: DIFlagPublic)
118+
!10 = !DICompositeType(tag: DW_TAG_array_type, baseType: !6, size: 352, align: 32, elements: !11)
119119
!11 = !{!12}
120120
!12 = !DISubrange(count: 11, lowerBound: 0)
121121
!13 = !DIGlobalVariableExpression(var: !14, expr: !DIExpression())

src/datalayout.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ impl MemoryLocation {
8585
MemoryLocation(Bytes(value))
8686
}
8787

88+
// see https://en.wikipedia.org/wiki/Data_structure_alignment#Computing_padding
8889
pub fn align_to(self, align: Bytes) -> Self {
8990
let align = align.value() - 1;
9091
MemoryLocation::new((self.value() + align) & !align)

src/typesystem.rs

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -621,7 +621,7 @@ impl DataTypeInformation {
621621
DataTypeInformation::String { size, encoding } => size
622622
.as_int_value(index)
623623
.map(|size| encoding.get_bytes_per_char() * size as u32)
624-
.map(Bytes::from_bits)
624+
.map(Bytes::new)
625625
.unwrap(),
626626
DataTypeInformation::Struct { members, .. } => members
627627
.iter()
@@ -669,15 +669,13 @@ impl DataTypeInformation {
669669
let type_layout = index.get_type_layout();
670670
match self {
671671
DataTypeInformation::Array { inner_type_name, .. } => {
672-
let inner_type = index.get_type_information_or_void(inner_type_name);
673-
if inner_type.get_alignment(index) > type_layout.i64 {
674-
type_layout.v128
675-
} else {
676-
type_layout.v64
677-
}
672+
index.get_type_information_or_void(inner_type_name).get_alignment(index)
678673
}
679674
DataTypeInformation::Struct { .. } => type_layout.aggregate,
680-
DataTypeInformation::String { .. } => type_layout.v64, //Strings are arrays
675+
DataTypeInformation::String { encoding, .. } => match encoding {
676+
StringEncoding::Utf8 => Bytes::new(1),
677+
StringEncoding::Utf16 => Bytes::new(2),
678+
},
681679
DataTypeInformation::Pointer { .. } => type_layout.p64,
682680
DataTypeInformation::Integer { size, semantic_size, .. } => {
683681
if let Some(1) = semantic_size {

0 commit comments

Comments
 (0)