| # DWARF Extensions | |
| LLDB supports some DWARF extensions produced by Clang. | |
| ## Clang `-gmodules` debug info | |
| On Darwin platforms, including Apple macOS and iOS, Clang can emit | |
| DWARF debug info for types found in [Clang | |
| modules](https://clang.llvm.org/docs/Modules.html) more efficiently. | |
| From an on-disk storage perspective, Clang modules are precompiled | |
| header files that contain serialized Clang ASTs of all the | |
| declarations found in a Clang module. In traditional DWARF debug info, | |
| two object files that were built from sources that imported the same | |
| header file will both contain DWARF debug type info for types in that | |
| header file. This can lead to a lot of redundant [debug | |
| info](https://llvm.org/devmtg/2015-10/#talk19). | |
| When Clang compiles a Clang module or precompiled header with the | |
| `-gmodules` option, the precompiled header (`.pch`) or module | |
| (`.pcm`) files become object file containers (on Darwin: Mach-O) | |
| that hold a `__clang_ast` section with the serialized Clang AST and | |
| various DWARF sections containing debug info for the type declarations | |
| found in the header or module. | |
| This allows Clang to omit these type definitions from the object | |
| (`.o`) files and replace them with forward declarations to save | |
| space. Type declarations in a Clang module are nested inside one | |
| `DW_TAG_module`, or -- in the case of submodules -- multiple levels | |
| of `DW_TAG_module`. If a DWARF DIE needs to reference a type DIE | |
| from another module, Clang emits a forward declaration of the | |
| referenced DIE into a `DW_TAG_module` inside the same compile unit. | |
| When a consumer sees a forward declaration that is nested inside a | |
| `DW_TAG_module`, it knows that it can find the full type declaration | |
| in an external `.pcm` or `.pch` file. To facilitate locating these | |
| external dependencies, Clang emits skeleton CUs into each object file | |
| that references external modules. Clang uses the same mechanism that | |
| is used to locate external `.dwo` files on ELF-based platforms. The | |
| `DW_AT_GNU_dwo_name` contains the absolute path to the `.pcm` | |
| file, and the `DW_AT_GNU_dwo_id` is a hash of the contents that is | |
| repeated in the `DW_TAG_compile_unit` of the `.pcm` file. | |
| For example: | |
| M.h | |
| ``` | |
| struct A { | |
| int x; | |
| }; | |
| ``` | |
| M.pcm | |
| ``` | |
| DW_TAG_compile_unit | |
| DW_AT_GNU_dwo_id (0xabcdef) | |
| DW_TAG_module | |
| DW_AT_name "M" | |
| DW_TAG_structure | |
| DW_AT_name "A" | |
| DW_TAG_member | |
| DW_AT_name "x" | |
| ``` | |
| A.c | |
| ``` | |
| A a; | |
| ``` | |
| A.o | |
| ``` | |
| DW_TAG_compile_unit | |
| DW_TAG_module | |
| DW_AT_name "M" | |
| DW_TAG_structure | |
| DW_AT_name "A" | |
| DW_AT_declaration (true) | |
| DW_TAG_variable | |
| DW_AT_name "a" | |
| DW_AT_type (local ref to fwd decl "A") | |
| DW_TAG_compile_unit | |
| DW_AT_GNU_dwo_id (0xabcdef) | |
| DW_AT_GNU_dwo_name ("M.pcm") | |
| ``` | |
| The debug info inside a `.pcm` file may recursively reference | |
| further external types that are defined in other `.pcm` files. Clang | |
| generates external references (and debug info inside the modules) for | |
| the following types: | |
| C: | |
| - `struct` | |
| - `union` | |
| - `enum` | |
| - `typedef` | |
| Objective-C: | |
| - all the C types listed above | |
| - `@interface` | |
| C++: | |
| - all the C types listed above | |
| - `namespace` | |
| - any explicit `extern template` specializations | |
| LLDB supports this DWARF extension only when debugging from `.o` | |
| files. The `dsymutil` debug info linker also understands this format | |
| and will resolve all module type references to point straight to the | |
| underlying defining declaration. Because of this a `.dSYM` bundle | |
| will never contain any `-gmodules`-style references. | |
| ## Apple SDK information | |
| Clang and the Swift compiler emit information about the Xcode SDK that | |
| was used to build a translation unit into the `DW_TAG_compile_unit`. | |
| The `DW_AT_LLVM_sysroot` attribute points to the SDK root | |
| (equivalent to Clang's `-isysroot` option). The `DW_AT_APPLE_sdk` | |
| attribute contains the name of the SDK, for example `MacOSX.sdk`. | |
| ## Objective-C runtime | |
| Clang emits the Objective-C runtime version into the | |
| `DW_TAG_compile_unit` using the | |
| `DW_AT_APPLE_major_runtime_vers` attribute. The value 2 stands | |
| for Objective-C 2.0. |