1 --- 2 title: 'SAOC LLDB D integration: 15th Weekly Update' 3 date: '2021-12-30T23:00:00+01:00' 4 tags: ['saoc', 'saoc2021', 'dlang', 'llvm', 'lldb', 'debug', 'debugging', 'dwarf'] 5 description: "This post describes what I've done on the 15th week of the 6 Symmetry Autumn of Code 2021, including some patches on the upstream about LLD, 7 implement type value dumping and start implementing other built-in types along 8 with some problems with real type." 9 --- 10 11 Hi D community! 12 13 Sorry for being late. I'm here again, to describe what I've done during the 14 fifteenth week of Symmetry Autumn of Code. 15 16 ## LLVM upstream changes: LLD D demangling 17 18 I didn't work on the demangler patches but I touched on some other existing 19 ones, such as implementation of `DW_TAG_immutable_type` on the LLVM core which 20 had some missing pieces and added tests. (See 21 [here](https://reviews.llvm.org/D113633)) 22 23 I also added support for other demanglers other than Itanium on LLD linker. 24 This included the freshly added D demangler along with Rust and other future 25 demanglers added to LLVM core. 26 27 So now instead of: 28 29 ``` 30 app.d:16: error: undefined reference to '_D3app7noexistFZi' 31 ``` 32 33 You will have this: 34 35 ``` 36 app.d:16: error: undefined reference to 'app.noexist()' 37 ``` 38 39 This came along with my work on adding D demangler on the LLVM core. You can 40 read more about this change, [here](https://reviews.llvm.org/D116279). 41 42 ## Type name dumping and value dumping 43 44 I added D type kind mapping to type name for the rest of the built-in types. 45 46 I also have found the missing part to make value dumping working. I needed to 47 implement two missing parts: 48 49 - A way to discover the bit size based on the D type wrapper type kind. 50 - A way to get the type information based on a type kind using 51 `lldb::TypeFlags` 52 53 This way LLDB can understand if a certain type kind is built-in, has value, is 54 signed, is integer, is scalar, etc... 55 56 So finally, I can print a simple runtime boolean value: 57 58 ``` 59 (lldb) ta v 60 Global variables for app.d in app: 61 (bool) app.falseval = false 62 (bool) app.trueval = true 63 ``` 64 65 You can consult the source code for those changes 66 [here](https://github.com/devtty63/llvm-project/tree/lldb-d/implement-typesystem-d). 67 68 ## Expanding value dumping to other built-in types 69 70 Having this implemented, I now need to compare and check if the DWARF bit size 71 and encoding match a certain D type kind. The implementation of other types are 72 not yet pushed, since I faced a problem while adding logic to platform-specific 73 size types, such as `real`. 74 75 ### The `real` problem 76 77 Since `real` is, according to D specification, platform-specific, I need to 78 accomudate the right bit size according to a certain target and discover the 79 right floating point encoding. This quite a challange because DWARF doesn't 80 specify the floating point encoding. To try to understand why, I did a bit of 81 research about that, and found 82 [this](https://gcc.gnu.org/legacy-ml/gcc/2015-10/msg00015.html) mailing list 83 thread from 2015 about distiguish different floating point encoding in DWARF. 84 85 Right now, there is no way and it seems there is no intention to distiguish 86 target-specific floating point formats on DWARF, because according to them, 87 this should be specified on the target ABI. But what if the ABI doesn't specify 88 this behaviour? We should at least have a way to distiguish IEEE interchangable 89 format and non-interchangable formats, like 128-bit x86 SSE floating points. 90 91 Fortunately, we don't have to worry much about this, since we don't use 128-bit 92 in any of D implementation, although our spec say: 93 94 real: largest floating point size available 95 96 Implementation Defined: The real floating point type has at least the range 97 and precision of the double type. On x86 CPUs it is often implemented as 98 the 80 bit Extended Real type supported by the x86 FPU. 99 100 This is wrong, because, AFAIK, on x86-64 System V ABI, 128-bit floating point 101 is the largest available, since AMD64 CPUs are required to have at least SSE 102 extensions, which have support for 128-bit XMM registers to perform 103 floating-point operations. 104 105 So, LDC and DMD generates binaries with System V as target ABI but uses x87 FPU 106 instead of SSE for `real`, which means they are out of spec? 107 108 Anyway, according to Mathias and as I suggested, the simple way to do this is 109 to hardcode this according the target triple and the DWARF type name, but I 110 think this can be problematic for either when we support 128-bit floats or when 111 the ABI doesn't specify the floating point encoding format. 112 113 That said, I would like to have some thoughts on this, specially if someone 114 knows if there is any special case for certain targets and how DMD/LDC/GDC 115 interprets the D spec and target ABI spec. 116 117 ## What is next? 118 119 I plan to finish support for built-in type value dumping and hopefully start 120 implementing DIDerivedType which includes DWARF tags for `const` type 121 modifiers, `alias`/`typedef`s,... 122 123 You can also read this on the D programming language forum, 124 [here](https://firstname.lastname@example.org), 125 and discuss there! 126 127 Read about the [previous week](../d-saoc-2021-14/) and [next 128 week](../d-saoc-2021-16/).