PLC-lang / rusty

Structured Text Parser and LLVM Frontend
GNU Lesser General Public License v3.0
223 stars 53 forks source link

fix: DebugInfo alignment and offset for aggregate types #1329

Closed mhasel closed 1 month ago

mhasel commented 1 month ago

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:

#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:

!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)
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:

!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