2184 Commits

Author SHA1 Message Date
nerix
7bda76367f
[LLDB][NativePDB] Ignore functions with no type in name lookup (#153382)
Some functions don't have the `FunctionType` set. We can't look these up
and won't be able to call them, so ignore them when caching the function
names.

This does fix the failures caused by
https://github.com/llvm/llvm-project/pull/153160 mentioned in
https://github.com/llvm/llvm-project/pull/153160#issuecomment-3183062431.
However, in `lldb-shell::msstl_smoke.cpp` there's another failure not
introduced by #153160 (fixed with #153386).
2025-08-14 14:23:39 +01:00
Kazu Hirata
bfc331e544 [lldb] Fix warnings
This patch fixes:

  lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp:647:3:
  error: 'llvm::Expected' may not intend to support class template
  argument deduction [-Werror,-Wctad-maybe-unsupported]

  lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp:677:3:
  error: 'llvm::Expected' may not intend to support class template
  argument deduction [-Werror,-Wctad-maybe-unsupported]
2025-08-13 09:22:25 -07:00
nerix
3f61e4eae6
[LLDB][NativePDB] Resolve declaration for tag types (#152579)
Tag types like stucts or enums didn't have a declaration attached to
them. The source locations are present in the IPI stream in
`LF_UDT_MOD_SRC_LINE` records:

```
   0x101F | LF_UDT_MOD_SRC_LINE [size = 18, hash = 0x1C63]
            udt = 0x1058, mod = 3, file = 1, line = 0
   0x2789 | LF_UDT_MOD_SRC_LINE [size = 18, hash = 0x1E5A]
            udt = 0x1253, mod = 35, file = 93, line = 17069
```

The file is an ID in the string table `/names`:

```
     ID | String
      1 | '\<unknown>'
     12 | 'D:\a\_work\1\s\src\ExternalAPIs\WindowsSDKInc\c\Include\10.0.22621.0\um\wingdi.h'
     93 | 'D:\a\_work\1\s\src\ExternalAPIs\WindowsSDKInc\c\Include\10.0.22621.0\um\winnt.h'
```

Here, we're not interested in `mod`. This would indicate which module
contributed the UDT.

I was looking at Rustc's PDB and found that it uses `<unknown>` for some
types, so I added a check for that.

This makes two DIA PDB shell tests to work with the native PDB plugin.

---------

Co-authored-by: Michael Buch <michaelbuch12@gmail.com>
2025-08-13 14:47:21 +01:00
nerix
44f41f55b4
Reland "[LLDB][NativePDB] Find functions by basename" ( #152295) (#153160)
Relands #152295.

Checking for the overloads did not account for them being out of order.
For example, [the failed
output](https://github.com/llvm/llvm-project/pull/152295#issuecomment-3177563247)
contained the overloads, but out of order. The last commit here fixes
that by using `-DAG`.

---------

Co-authored-by: Jonas Devlieghere <jonas@devlieghere.com>
2025-08-12 12:49:47 -05:00
Jonas Devlieghere
3a682864d9
Revert "[LLDB][NativePDB] Find functions by basename" (#153131)
Reverts llvm/llvm-project#152295
2025-08-11 22:23:20 -05:00
nerix
7e2cc725db
[LLDB][NativePDB] Find functions by basename (#152295)
This adds the ability for functions to be matched by their basename.

Before, the globals were searched for the name. This works if the full
name is available but fails for basenames.
PDB only includes the full names of functions, so we need to cache all
basenames. This is (again) very similar to
[SymbolFilePDB](b242150b07/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp (L1291-L1383)).
There are two main differences:

- We can't just access the parent of a function to determine that it's a
member function - we need to check the type of the function, and its
"this type".
- SymbolFilePDB saved the full method name in the map. However, when
searching for methods, only the basename is passed, so the function
never found any methods.

Fixes #51933.

---------

Co-authored-by: Jonas Devlieghere <jonas@devlieghere.com>
2025-08-11 20:51:37 -05:00
Matheus Izvekov
91cdd35008
[clang] Improve nested name specifier AST representation (#147835)
This is a major change on how we represent nested name qualifications in
the AST.

* The nested name specifier itself and how it's stored is changed. The
prefixes for types are handled within the type hierarchy, which makes
canonicalization for them super cheap, no memory allocation required.
Also translating a type into nested name specifier form becomes a no-op.
An identifier is stored as a DependentNameType. The nested name
specifier gains a lightweight handle class, to be used instead of
passing around pointers, which is similar to what is implemented for
TemplateName. There is still one free bit available, and this handle can
be used within a PointerUnion and PointerIntPair, which should keep
bit-packing aficionados happy.
* The ElaboratedType node is removed, all type nodes in which it could
previously apply to can now store the elaborated keyword and name
qualifier, tail allocating when present.
* TagTypes can now point to the exact declaration found when producing
these, as opposed to the previous situation of there only existing one
TagType per entity. This increases the amount of type sugar retained,
and can have several applications, for example in tracking module
ownership, and other tools which care about source file origins, such as
IWYU. These TagTypes are lazily allocated, in order to limit the
increase in AST size.

This patch offers a great performance benefit.

It greatly improves compilation time for
[stdexec](https://github.com/NVIDIA/stdexec). For one datapoint, for
`test_on2.cpp` in that project, which is the slowest compiling test,
this patch improves `-c` compilation time by about 7.2%, with the
`-fsyntax-only` improvement being at ~12%.

This has great results on compile-time-tracker as well:

![image](https://github.com/user-attachments/assets/700dce98-2cab-4aa8-97d1-b038c0bee831)

This patch also further enables other optimziations in the future, and
will reduce the performance impact of template specialization resugaring
when that lands.

It has some other miscelaneous drive-by fixes.

About the review: Yes the patch is huge, sorry about that. Part of the
reason is that I started by the nested name specifier part, before the
ElaboratedType part, but that had a huge performance downside, as
ElaboratedType is a big performance hog. I didn't have the steam to go
back and change the patch after the fact.

There is also a lot of internal API changes, and it made sense to remove
ElaboratedType in one go, versus removing it from one type at a time, as
that would present much more churn to the users. Also, the nested name
specifier having a different API avoids missing changes related to how
prefixes work now, which could make existing code compile but not work.

How to review: The important changes are all in
`clang/include/clang/AST` and `clang/lib/AST`, with also important
changes in `clang/lib/Sema/TreeTransform.h`.

The rest and bulk of the changes are mostly consequences of the changes
in API.

PS: TagType::getDecl is renamed to `getOriginalDecl` in this patch, just
for easier to rebasing. I plan to rename it back after this lands.

Fixes #136624
Fixes https://github.com/llvm/llvm-project/issues/43179
Fixes https://github.com/llvm/llvm-project/issues/68670
Fixes https://github.com/llvm/llvm-project/issues/92757
2025-08-09 05:06:53 -03:00
Michael Buch
ef30dd34e9
[lldb][SymbolFileDWARF][NFC] Add FindFunctionDefinition helper (#152733)
Factors out code to locate a definition DIE from a `FunctionCallLabel`
into a helper. This will be useful for an upcoming refactor that extends
`FindFunctionDefinition`.

Drive-by:
* adjusts some error messages in the `FunctionCallLabel` support code.
2025-08-08 18:23:58 +01:00
Dave Lee
2959051e65
[lldb] Preserve original symbol of Mangled function names (#152201)
Fixes a bug that surfaces in frame recognizers.

Details about the bug:

A new frame recognizer is configured to match a specific symbol
(`swift_willThrow`). This is an `extern "C"` symbol defined in a C++
source file. When Swift is built with debug info, the function
`ParseFunctionFromDWARF` will use the debug info to construct a function
name that looks like a C++ declaration (`::swift_willThrow(void *,
SwiftError**)`). The `Mangled` instance will have this string as its
`m_demangled` field, and have _no_ string for its `m_mangled` field.

The result is the frame recognizer would not match the symbol to the
name (`swift_willThrow` != `::swift_willThrow(void *, SwiftError**)`.

By changing `ParseFunctionFromDWARF` to assign both a demangled name and
a mangled, frame recognizers can successfully match symbols in this
configuration.
2025-08-05 21:23:46 -07:00
nerix
2d4e5c4e1f
[LLDB][NativePDB] Use undecorated name for types if UniqueName isn't mangled (#152114)
Languages other than C/C++ don't necessarily emit mangled names in the
`UniqueName` field of type records. Rust specifically emits a unique ID
that doesn't contain the name.

For example, `(i32, i32)` is emitted as

```llvm
!266 = !DICompositeType(
  tag: DW_TAG_structure_type, name: "tuple$<i32,i32>", file: !9, size: 64, align: 32,
  elements: !267, templateParams: !17, identifier: "19122721b0632fe96c0dd37477674472"
)
```

which results in

```
  0x1091 | LF_STRUCTURE [size = 72, hash = 0x1AC67] `tuple$<i32,i32>`
           unique name: `19122721b0632fe96c0dd37477674472`
           vtable: <no type>, base list: <no type>, field list: 0x1090
           options: has unique name, sizeof 8
```

In C++ with Clang and MSVC, a structure similar to this would result in
```
   0x136F | LF_STRUCTURE [size = 44, hash = 0x30BE2] `MyTuple`
            unique name: `.?AUMyTuple@@`
            vtable: <no type>, base list: <no type>, field list: 0x136E
            options: has unique name, sizeof 8
```

With this PR, if a `UniqueName` is encountered that couldn't be parsed,
it will fall back to using the undecorated (→ do the same as if the
unique name is empty/unavailable).

I'm not sure how to test this. Maybe compiling the LLVM IR that rustc
emits?

Fixes #152051.
2025-08-05 19:57:26 -07:00
nerix
852cc9200f
[LLDB][NativePDB] Implement FindNamespace (#151950)
`FindNamespace` was not implemented for `SymbolFileNativePDB`. Without
it, it wasn't possible to lookup items through namespaces when
evaluating expressions.

This is mostly the same as in
[SymbolFilePDB](f1eb869bae/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp (L1664-L1696))
as well as
[PDBAstParser](f1eb869bae/lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp (L1126-L1150)):
The AST parser/builder saves the created namespaces in a map to lookup
when a namespace is requested.

This is working towards making
[Shell/SymbolFile/PDB/expressions.test](f1eb869bae/lldb/test/Shell/SymbolFile/PDB/expressions.test)
pass with the native PDB plugin.
2025-08-05 11:10:27 +01:00
Michael Buch
4b31b4ebdd [lldb][DWARFIndex][NFC] Remove DWARFIndex::IterationActionAdaptor
Now that all `DWARFIndex` APIs have been converted to use
`IterationAction`, the `IterationActionAdaptor` is unused.
2025-08-05 10:30:46 +01:00
Michael Buch
d276569258
[lldb][DWARFIndex] Adapt DebugNamesDWARFIndex::ProcessEntry to IterationAction (#152025)
Continuation of https://github.com/llvm/llvm-project/pull/151489
2025-08-04 21:33:05 +01:00
Michael Buch
147cfc89f0
[lldb][DWARFIndex] Adapt DWARFIndex DIERefCallback to IterationAction (#152001)
Continuation of https://github.com/llvm/llvm-project/pull/151489
2025-08-04 18:44:42 +01:00
Michael Buch
37b6fbc95b
[lldb][DWARFIndex] Adapt DWARFIndex GetTypes APIs to IterationAction (#151992)
Continuation of https://github.com/llvm/llvm-project/pull/151489
2025-08-04 17:48:16 +01:00
nerix
7b208e04b2
[LLDB] Add setting for native PDB reader (#151490)
Initially suggested in
https://github.com/llvm/llvm-project/pull/149305#issuecomment-3113413702
- this PR adds the setting `plugin.symbol-file.pdb.use-native-reader`.
It doesn't remove support for `LLDB_USE_NATIVE_PDB_READER` to allow some
backwards compatibility. This was the suggested way to use the native
reader - changing that would mean users who set this, now use the DIA
reader. The setting has priority over the environment variable, though.
If the default gets flipped on Windows, the environment variable could
probably be removed as well.

This would make it possible to test both native PDB and DIA PDB in the
API tests (see linked PR).
2025-08-04 09:43:01 -07:00
Michael Buch
8d9afb8d95
[lldb][DWARFIndex] Adapt DWARFIndex ObjC APIs to IterationAction (#151839)
Continuation of https://github.com/llvm/llvm-project/pull/151489
2025-08-04 17:07:01 +01:00
nerix
d95dadff8f
[LLDB][NativePDB] Allow type lookup in namespaces (#149876)
Previously, `type lookup` for types in namespaces didn't work with the
native PDB plugin, because `FindTypes` would only look for types whose
base name was equal to their full name. PDB/CodeView does not store the
base names in the TPI stream, but the types have their full name (e.g.
`std::thread` instead of `thread`). So `findRecordsByName` would only
return types in the top level namespace.

This PR changes the lookup to go through all types and check their base
name. As that could be a bit expensive, the names are first cached
(similar to the function lookup in the DIA PDB plugin). Potential types
are checked with `TypeQuery::ContextMatches`.

To be able to handle anonymous namespaces, I changed
`TypeQuery::ContextMatches`. The [`TypeQuery`
constructor](9ad7edef42/lldb/source/Symbol/Type.cpp (L76-L79))
inserts all name components as `CompilerContextKind::AnyDeclContext`. To
skip over anonymous namespaces, `ContextMatches` checked if a component
was empty and exactly of kind `Namespace`. For our query, the last check
was always false, so we never skipped anonymous namespaces. DWARF
doesn't have this problem, as it [constructs the context
outside](abe93d9d7e/lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.cpp (L154-L160))
and has proper information about namespaces. I'm not fully sure if my
change is correct and that it doesn't break other users of `TypeQuery`.

This enables `type lookup <type>` to work on types in namespaces.
However, expressions don't work with this yet, because `FindNamespace`
is unimplemented for native PDB.
2025-08-04 08:56:04 +01:00
Michael Buch
0bdb4a3646
[lldb][DWARFIndex][NFC] Change GetNamespace/GetGlobalVariables APIs to use IterationAction (#151668)
Continuation from https://github.com/llvm/llvm-project/pull/151489
2025-08-02 15:28:10 +01:00
Michael Buch
f89059140b
[lldb][Expression] Encode Module and DIE UIDs into function AsmLabels (#148877)
LLDB currently attaches `AsmLabel`s to `FunctionDecl`s such that that
the `IRExecutionUnit` can determine which mangled name to call (we can't
rely on Clang deriving the correct mangled name to call because the
debug-info AST doesn't contain all the info that would be encoded in the
DWARF linkage names). However, we don't attach `AsmLabel`s for structors
because they have multiple variants and thus it's not clear which
mangled name to use. In the [RFC on fixing expression evaluation of
abi-tagged
structors](https://discourse.llvm.org/t/rfc-lldb-handling-abi-tagged-constructors-destructors-in-expression-evaluator/82816)
we discussed encoding the structor variant into the `AsmLabel`s.
Specifically in [this
thread](https://discourse.llvm.org/t/rfc-lldb-handling-abi-tagged-constructors-destructors-in-expression-evaluator/82816/7)
we discussed that the contents of the `AsmLabel` are completely under
LLDB's control and we could make use of it to uniquely identify a
function by encoding the exact module and DIE that the function is
associated with (mangled names need not be enough since two identical
mangled symbols may live in different modules). So if we already have a
custom `AsmLabel` format, we can encode the structor variant in a
follow-up (the current idea is to append the structor variant as a
suffix to our custom `AsmLabel` when Clang emits the mangled name into
the JITted IR). Then we would just have to teach the `IRExecutionUnit`
to pick the correct structor variant DIE during symbol resolution. The
draft of this is available
[here](https://github.com/llvm/llvm-project/pull/149827)

This patch sets up the infrastructure for the custom `AsmLabel` format
by encoding the module id, DIE id and mangled name in it.

**Implementation**

The flow is as follows:
1. Create the label in `DWARFASTParserClang`. The format is:
`$__lldb_func:module_id:die_id:mangled_name`
2. When resolving external symbols in `IRExecutionUnit`, we parse this
label and then do a lookup by DIE ID (or mangled name into the module if
the encoded DIE is a declaration).

Depends on https://github.com/llvm/llvm-project/pull/151355
2025-08-01 07:21:41 +01:00
Jonas Devlieghere
e1d45b1b97
[lldb] Fix a use-after-free in SymbolFileCTF (#151586)
This fixes a use-after-free in SymbolFileCTF. Previously, we would
remove the underlying CTF type as soon as we resolved it. However, it's
possible that we're still holding onto the CTF type while we're parsing
a dependent type, like a modifier, resulting in a use-after-free. This
patch addresses the issue by delaying the removal of the CTF type until
the type is fully resolved.

I have a XNU kernel binary that reproduces the issue and confirmed that
this solves the memory issue using ASan. However I haven't been able to
craft types by hand that reproduce this issue for a test case.

rdar://156660866
2025-07-31 14:15:20 -07:00
Michael Buch
550058c58b
[lldb][DWARFIndex][NFC] Change GetFunctions return type to IterationAction (#151489)
The ultimate goal is to replace the return types of all the `DWARFIndex`
callbacks to `IterationAction`. To reduce the blast radius and do this
incrementally I'm doing this for `GetFunctions` only here. I added a
`IterationActionAdaptor` helper (that will ultimately get removed once
all APIs have been migrated) to avoid having to change too many other
APIs that `GetFunctions` interacts with.
2025-07-31 20:23:19 +01:00
Michael Buch
7410f6d31d
[lldb][TypeSystemClang] Make AsmLabel parameter a llvm::StringRef (#151355)
Split out from https://github.com/llvm/llvm-project/pull/148877

This patch prepares `TypeSystemClang` APIs to take `AsmLabel`s which
concatenated strings (hence `std::string`) instead of a plain `const
char*`.
2025-07-31 07:11:30 +01:00
Jonas Devlieghere
c2548a8c4c
[lldb] Support DW_OP_WASM_location in DWARFExpression (#151010)
Add support for DW_OP_WASM_location in DWARFExpression. This PR rebases
#78977 and cleans up the unit test. The DWARF extensions are documented
at https://yurydelendik.github.io/webassembly-dwarf/ and supported by
LLVM-based toolchains such as Clang, Swift, Emscripten, and Rust.
2025-07-30 09:20:37 -07:00
nerix
6be3cc5ad5
[LLDB][NativePDB] Fix name access for classes in CVTagRecord::name (#151190)
From
https://github.com/llvm/llvm-project/pull/149876#discussion_r2240478480:
The `name()` accessor checked for `m_kind == Union` and accessed
`cvclass` instead of `cvunion`. This is technically wrong (maybe UB
even?).
In practice, this wasn't an issue, because all types in the union
(`ClassRecord`/`EnumRecord`/`UnionRecord`) inherit from `TagRecord`.
2025-07-30 09:11:57 -07:00
Daniel Sanders
726502d668
[lldb] Fix UB cast when encountering DW_LANG_* >= eNumLanguageTypes (#150132)
LanguageType has two kinds of enumerators in it. The first is
DWARF-assigned enumerators which must be consecutive and match DW_LANG
values. The second is the vendor-assigned enumerators which must be
unique and must follow on from the DWARF-assigned values (i.e. the first
one is currently eLanguageTypeMojo + 1) even if that collides with
DWARF-assigned values that lldb is not yet aware of

Only the DWARF-assigned enumerators may be static_cast from DW_LANG
since their values match. The vendor-assigned enumerators must be
explicitly converted since their values do not match. This needs to
handle new languages added to DWARF and not yet implemented in lldb.

This fixes a crash when encountering a DW_LANG value >=
eNumLanguageTypes and wrong behaviour when encountering DW_LANG values
that have not yet been added to LanguageType but happen to coincide with
a vendor-assigned enumerator due to the consecutive values requirement
described above.

Another way to fix the crash is to add the language to LanguageType (and
fill any preceeding gaps in the number space) so that the DW_LANG being
encountered is correctly handled but this just moves the problem to a
new subset of DW_LANG values.

Also fix an unnecessary static-cast from LanguageType to LanguageType.
2025-07-22 17:45:13 -07:00
Jonas Devlieghere
2cb1ecb94b
[lldb] Eliminate namespace lldb_private::dwarf (NFC) (#150073)
Eliminate the `lldb_private::dwarf` namespace, in favor of using
`llvm::dwarf` directly. The latter is shorter, and this avoids ambiguity
in the ABI plugins that define a `dwarf` namespace inside an anonymous
namespace.
2025-07-22 15:51:00 -07:00
Hemang Gadhavi
0a357e92ca
[lldb] Update the String table offset based on the DWARF format (#147054)
This PR is updating the string table offset (DW_AT_str_offsets_base
which is introduced in `DWARF5`) based on the DWARF format, as per the
DWARF specification; For the 32-bit DWARF format, each offset is 4 bytes
long; for the 64-bit DWARF format, each offset is 8 bytes long.
2025-07-14 15:25:45 +05:30
qxy11
7bd06c41a3
Defer loading all DWOs by default when dumping separate_debug-info (#146166)
### Summary
Currently `target modules dump separate separate-debug-info`
automatically loads up all DWO files, even if deferred loading is
enabled through debug_names. Then, as expected all DWO files (assuming
there is no error loading it), get marked as "loaded".

This change adds the option `--force-load-all-debug-info` or `-f` for
short to force loading all debug_info up, if it hasn't been loaded yet.
Otherwise, it will change default behavior to not load all debug info so
that the correct DWO files will show up for each modules as "loaded" or
not "loaded", which could be helpful in cases where we want to know
which particular DWO files were loaded.

### Testing
#### Unit Tests
Added additional unit tests
`test_dwos_load_json_with_debug_names_default` and
`test_dwos_load_json_with_debug_names_force_load_all` to test both
default behavior and loading with the new flag
`--force-load-all-debug-info`, and changed expected behavior in
`test_dwos_loaded_symbols_on_demand`.
```
bin/lldb-dotest -p TestDumpDwo ~/llvm-project/lldb/test/API/commands/target/dump-separate-debug-info/dwo
```

#### Manual Testing
Compiled a simple binary w/ `--gsplit-dwarf --gpubnames` and loaded it
up:
```
(lldb) target create "./a.out"
Current executable set to '/home/qxy11/hello-world/a.out' (x86_64).
(lldb) help target modules dump separate-debug-info
List the separate debug info symbol files for one or more target modules.

Syntax: target modules dump separate-debug-info <cmd-options> [<filename> [<filename> [...]]]

Command Options Usage:
  target modules dump separate-debug-info [-efj] [<filename> [<filename> [...]]]

       -e ( --errors-only )
            Filter to show only debug info files with errors.

       -f ( --force-load-all-debug-info )
            Load all debug info files.

       -j ( --json )
            Output the details in JSON format.

     This command takes options and free-form arguments.  If your arguments resemble option specifiers (i.e., they start with a - or --), you must use ' -- ' between the end of the
     command options and the beginning of the arguments.
(lldb) target modules dump separate-debug-info --j
[
  {
    "separate-debug-info-files": [
      {  ...
        "dwo_name": "main.dwo",
        "loaded": false
      },
      {  ...
        "dwo_name": "foo.dwo",
        "loaded": false
      },
      { ...
        "dwo_name": "bar.dwo",
        "loaded": false
      }
    ],
  }
]
(lldb) b main
Breakpoint 1: where = a.out`main + 15 at main.cc:3:12, address = 0x00000000000011ff
(lldb) target modules dump separate-debug-info --j
[
  {
    "separate-debug-info-files": [
      { ...
        "dwo_name": "main.dwo",
        "loaded": true,
        "resolved_dwo_path": "/home/qxy11/hello-world/main.dwo"
      },
      { ...
        "dwo_name": "foo.dwo",
        "loaded": false
      },
      { ...
        "dwo_name": "bar.dwo",
        "loaded": false
      }
    ],
  }
]
(lldb) b foo
Breakpoint 2: where = a.out`foo(int) + 11 at foo.cc:12:11, address = 0x000000000000121b
(lldb) target modules dump separate-debug-info --j
[
  {
    "separate-debug-info-files": [
      { ...
        "dwo_name": "main.dwo",
        "loaded": true,
        "resolved_dwo_path": "/home/qxy11/hello-world/main.dwo"
      },
      { ...
        "dwo_name": "foo.dwo",
        "loaded": true,
        "resolved_dwo_path": "/home/qxy11/hello-world/foo.dwo"
      },
      { ...
        "dwo_name": "bar.dwo",
        "loaded": false
      }
    ],
  }
]
(lldb) b bar
Breakpoint 3: where = a.out`bar(int) + 11 at bar.cc:10:9, address = 0x000000000000126b
(lldb) target modules dump separate-debug-info --j
[
  {
    "separate-debug-info-files": [
      { ...
        "dwo_name": "main.dwo",
        "loaded": true,
        "resolved_dwo_path": "/home/qxy11/hello-world/main.dwo"
      },
      { ...
        "dwo_name": "foo.dwo",
        "loaded": true,
        "resolved_dwo_path": "/home/qxy11/hello-world/foo.dwo"
      },
      { ...
        "dwo_name": "bar.dwo",
        "loaded": true,
        "resolved_dwo_path": "/home/qxy11/hello-world/bar.dwo"
      }
    ],
  }
]
```
2025-07-07 12:01:22 -07:00
David Spickett
d8023e7cf8
[lldb] Use correct size when dumping DWARF64 DW_FORM_ref_addr (#146686)
Not that we ever do that, because this is unused code, but if someone
was debugging lldb I guess they'd call this.

Was missed in https://github.com/llvm/llvm-project/pull/145645

Relates to https://github.com/llvm/llvm-project/issues/135208
2025-07-03 11:33:59 +01:00
Michael Buch
58d84a615e
[lldb][DWARF][NFC] Reduce scope of ref_addr_size variable (#146557)
Follow-up to
https://github.com/llvm/llvm-project/pull/145645#discussion_r2174948997

There's no need for this variable to be declared at the function-level.
We reset it in all the cases where it's used anyway.

This patch just inlines the usage of the variable entirely.
2025-07-03 10:28:38 +01:00
Hemang Gadhavi
da0828b1e9
[lldb] Enable support for DWARF64 format handling (#145645)
This PR introduces support for the DWARF64 format, enabling handling of
64-bit DWARF sections as defined by the DWARF specification. The update
includes adjustments to header parsing and modification of form values
to accommodate 64-bit offsets and values.
Also Added the testcase to verify the DWARF64 format.
2025-07-01 18:35:40 +05:30
Pavel Labath
72b40f7c64
[lldb] Delete unused DWARFDataExtractor methods (#146356)
They are left over from our previous attempt at DWARF64. The new attempt
is not using them, and they also don't have equivalents in the llvm
DWARFDataExtractor class.
2025-07-01 08:47:45 +02:00
qxy11
9e3bb5bb91
Reland "[lldb] Add count for number of DWO files loaded in statistics #144424" (#145572)
This relands changes in #144424 for adding a count of DWO files
parsed/loaded and the total number of DWO files.

The previous PR was reverted in #145494 due to the newly added unit
tests failing on Windows and MacOS CIs since these platforms don't
support DWO. This change add an additional
`@add_test_categories(["dwo"])` to the new tests to
[skip](cd46354dbd/lldb/packages/Python/lldbsuite/test/test_categories.py (L56))
these tests on Windows/MacOS.

Original PR: #144424

### Testing
Ran unit tests
```
$ bin/lldb-dotest -p TestStats.py llvm-project/lldb/test/API/commands/statistics/basic/
----------------------------------------------------------------------
Ran 24 tests in 211.391s

OK (skipped=3)
```
2025-06-24 15:25:23 -07:00
Michael Buch
371f12f96d
Revert "[lldb] Add count for number of DWO files loaded in statistics" (#145494)
Reverts llvm/llvm-project#144424

Caused CI failures.

macOS CI failure was:
```
10:20:36  FAIL: test_dwp_dwo_file_count (TestStats.TestCase)
10:20:36      Test "statistics dump" and the loaded dwo file count.
10:20:36  ----------------------------------------------------------------------
10:20:36  Traceback (most recent call last):
10:20:36    File "/Users/ec2-user/jenkins/workspace/llvm.org/as-lldb-cmake/llvm-project/lldb/test/API/commands/statistics/basic/TestStats.py", line 639, in test_dwp_dwo_file_count
10:20:36      self.assertEqual(debug_stats["totalDwoFileCount"], 2)
10:20:36  AssertionError: 0 != 2
10:20:36  Config=arm64-/Users/ec2-user/jenkins/workspace/llvm.org/as-lldb-cmake/lldb-build/bin/clang
10:20:36  ======================================================================
10:20:36  FAIL: test_no_debug_names_eager_loads_dwo_files (TestStats.TestCase)
10:20:36      Test the eager loading behavior of DWO files when debug_names is absent by
10:20:36  ----------------------------------------------------------------------
10:20:36  Traceback (most recent call last):
10:20:36    File "/Users/ec2-user/jenkins/workspace/llvm.org/as-lldb-cmake/llvm-project/lldb/test/API/commands/statistics/basic/TestStats.py", line 566, in test_no_debug_names_eager_loads_dwo_files
10:20:36      self.assertEqual(debug_stats["totalDwoFileCount"], 2)
10:20:36  AssertionError: 0 != 2
10:20:36  Config=arm64-/Users/ec2-user/jenkins/workspace/llvm.org/as-lldb-cmake/lldb-build/bin/clang
10:20:36  ======================================================================
10:20:36  FAIL: test_split_dwarf_dwo_file_count (TestStats.TestCase)
10:20:36      Test "statistics dump" and the dwo file count.
10:20:36  ----------------------------------------------------------------------
10:20:36  Traceback (most recent call last):
10:20:36    File "/Users/ec2-user/jenkins/workspace/llvm.org/as-lldb-cmake/llvm-project/lldb/test/API/commands/statistics/basic/TestStats.py", line 588, in test_split_dwarf_dwo_file_count
10:20:36      self.assertEqual(len(debug_stats["modules"]), 1)
10:20:36  AssertionError: 42 != 1
10:20:36  Config=arm64-/Users/ec2-user/jenkins/workspace/llvm.org/as-lldb-cmake/lldb-build/bin/clang
```
2025-06-24 11:33:00 +01:00
Pavel Labath
46e1e9f104
Reapply "[lldb/cmake] Plugin layering enforcement mechanism (#144543)" (#145305)
The only difference from the original PR are the added BRIEF and
FULL_DOCS arguments to define_property, which are required for
cmake<3.23.
2025-06-24 11:10:35 +02:00
qxy11
3095d3a47d
[lldb] Add count for number of DWO files loaded in statistics (#144424)
## Summary
A new `totalLoadedDwoFileCount` and `totalDwoFileCount` counters to
available statisctics when calling "statistics dump".

1. `GetDwoFileCounts ` is created, and returns a pair of ints
representing the number of loaded DWO files and the total number of DWO
files, respectively. An override is implemented for `SymbolFileDWARF`
that loops through each compile unit, and adds to a counter if it's a
DWO unit, and then uses `GetDwoSymbolFile(false)` to check whether the
DWO file was already loaded/parsed.

3. In `Statistics`, use `GetSeparateDebugInfo` to sum up the total
number of loaded/parsed DWO files along with the total number of DWO
files. This is done by checking whether the DWO file was already
successfully `loaded` in the collected DWO data, anding adding to the
`totalLoadedDwoFileCount`, and adding to `totalDwoFileCount` for all CU
units.

## Expected Behavior
- When binaries are compiled with split-dwarf and separate DWO files,
`totalLoadedDwoFileCount` would be the number of loaded DWO files and
`totalDwoFileCount` would be the total count of DWO files.
- When using a DWP file instead of separate DWO files,
`totalLoadedDwoFileCount` would be the number of parsed compile units,
while `totalDwoFileCount` would be the total number of CUs in the DWP
file. This should be similar to the counts we get from loading separate
DWO files rather than only counting whether a single DWP file was
loaded.
- When not using split-dwarf, we expect both `totalDwoFileCount` and
`totalLoadedDwoFileCount` to be 0 since no separate debug info is
loaded.

## Testing
**Manual Testing**
On an internal script that has many DWO files, `statistics dump` was
called before and after a `type lookup` command. The
`totalLoadedDwoFileCount` increased as expected after the `type lookup`.
```
(lldb) statistics dump
{
  ...
  "totalLoadedDwoFileCount": 29,
}
(lldb) type lookup folly::Optional<unsigned int>::Storage
typedef std::conditional<true, folly::Optional<unsigned int>::StorageTriviallyDestructible, folly::Optional<unsigned int>::StorageNonTriviallyDestructible>::type
typedef std::conditional<true, folly::Optional<unsigned int>::StorageTriviallyDestructible, folly::Optional<unsigned int>::StorageNonTriviallyDestructible>::type
...
(lldb) statistics dump
{
  ...
  "totalLoadedDwoFileCount": 2160,
}
```
**Unit test**
Added three unit tests that build with new "third.cpp" and "baz.cpp"
files. For tests with w/ flags `-gsplit-dwarf -gpubnames`, this
generates 2 DWO files. Then, the test incrementally adds breakpoints,
and does a type lookup, and the count should increase for each of these
as new DWO files get loaded to support these.
```
$ bin/lldb-dotest -p TestStats.py ~/llvm-sand/external/llvm-project/lldb/test/API/commands/statistics/basic/
----------------------------------------------------------------------
Ran 20 tests in 211.738s

OK (skipped=3)
```
2025-06-23 11:51:08 -07:00
Michael Buch
1bc63265af
[lldb][DWARFASTParserClang] Support constant index encoding of DW_AT_object_pointer (#144998)
Starting with https://github.com/llvm/llvm-project/pull/124790, Clang
emits `DW_AT_object_pointer` encoded as integer constants rather than
DIE references. This patch accounts for this.

Depends on https://github.com/llvm/llvm-project/pull/145328 and
https://github.com/llvm/llvm-project/pull/145126
2025-06-23 17:58:17 +01:00
Michael Buch
5a16645a3d
Reland "[lldb][DWARF] Remove object_pointer from ParsedDWARFAttributes (#145065)" (#145126)
This reverts commit 877511920dcf36463e06746d626e8876583a6abd.

This fixes the `TestObjCInBlockVars.py` LLDB API test.

The issue was that `GetCXXObjectParameter` wouldn't deduce the object
parameter of Objective-C method definitions correctly. In DWARF those
don't have a `DW_AT_specification` (so no link back to a DeclContext
that is a class type). The fix is to only check the validity of the
DeclContext DIE *if* no `DW_AT_object_pointer` exists on the DIE. If
`DW_AT_object_pointer` does exist, we should just always use that as the
object_parameter.
2025-06-23 17:26:23 +01:00
Michael Buch
634fe0de50
[lldb][DWARF] Support retrieving DW_FORM_implicit_const value with DWARFDebugInfoEntry::GetAttributeValue (#145328)
`DWARFFormValue::ExtractValue` has nothing to extract for
`DW_FORM_implicit_const` since the value is stored in the abbreviation.
`DWARFFormValue` expects the user to have set the value of the
implicit_const. This patch does so in `GetAttributeValue`.
2025-06-23 17:25:57 +01:00
Pavel Labath
18f667d804 Revert "[lldb/cmake] Plugin layering enforcement mechanism (#144543)"
Causes failures on several bots.

This reverts commits 714b2fdf3a385e5b9a95c435f56b1696ec3ec9e8 and
e7c1da7c8ef31c258619c1668062985e7ae83b70.
2025-06-23 12:07:10 +02:00
Pavel Labath
e7c1da7c8e
[lldb/cmake] Plugin layering enforcement mechanism (#144543)
Some inter-plugin dependencies are okay, others are not. Yet others not,
but we're sort of stuck with them. The idea is to be able to prevent
backsliding while making sure that acceptable dependencies are..
accepted. For context, see
https://github.com/llvm/llvm-project/pull/139170 and the attached
changes to the documentation.
2025-06-23 11:31:26 +02:00
Michael Buch
d2c0451d05 [lldb][DWAFASTParserClang][NFC] Rename GetCXXObjectParameter to GetObjectParameter
Since this is used for Objective-C too.
2025-06-22 11:41:48 +01:00
Michael Buch
877511920d
Revert "[lldb][DWARF] Remove object_pointer from ParsedDWARFAttributes" (#145065)
Reverts llvm/llvm-project#144880

Caused `TestObjCIvarsInBlocks.py` to fail on macOS CI.
2025-06-20 17:20:58 +01:00
Michael Buch
b017b4ce9a
[lldb][DWARF] Remove object_pointer from ParsedDWARFAttributes (#144880)
We can just always use `GetCXXObjectParameter` instead. We've only used
this attribute to set the object parameter name on ClangASTMetadata,
which doesn't seem like good enough justification to keep it around.

Depends on https://github.com/llvm/llvm-project/pull/144879
2025-06-20 16:01:55 +01:00
Michael Buch
dae5104eed
[lldb][DWARFASTParserClang] Make GetCXXObjectParameter public and call it from unit-tests (#144879)
My goal is to remove the `object_pointer` member on
`ParsedDWARFTypeAttributes` since it's duplicating information that we
retrieve with `GetCXXObjectParameter` anyway. To continue having
coverage for the `DW_AT_object_pointer` code-paths, instead of checking
the
`attrs.object_pointer` I'm now calling `GetCXXObjectParameter` directly.
We could find some very roundabout way to go via the Clang AST to check
that the object parameter was parsed correctly, but that quickly became
quite painful.

Depends on https://github.com/llvm/llvm-project/pull/144876
2025-06-19 13:42:23 +01:00
Michael Buch
30824c449a
[lldb][DWARFASTParserClang] GetCXXObjectParameter to take DeclContext DIE parameter (#144876)
I'm trying to call `GetCXXObjectParameter` from unit-tests in a
follow-up patch and taking a `DWARFDIE` instead of `clang::DeclContext`
makes that much simpler. These should be equivalent, since all we're
trying to check is that the parent context is a record type.
2025-06-19 12:48:39 +01:00
Michael Buch
c3ec9e3f65
[lldb][DWARF] Don't try to compute address range information of forward declarations (#144059)
This fixes the error reported in
https://github.com/llvm/llvm-project/pull/144037.

When computing the aranges table of a CU, LLDB would currently visit all
`DW_TAG_subprogram` DIEs and check their
`DW_AT_low_pc`/`DW_AT_high_pc`/`DW_AT_ranges` attributes. If those don't
exist it would error out and spam the console. Some subprograms
(particularly forward declarations) don't have low/high pc attributes,
so it's not really an "error". See DWARFv5 spec section `3.3.3
Subroutine and Entry Point Locations`:
```
A subroutine entry may have either a DW_AT_low_pc and DW_AT_high_pc
pair of attributes or a DW_AT_ranges attribute whose values encode the
contiguous or non-contiguous address ranges, respectively, of the machine
instructions generated for the subroutine (see Section 2.17 on page 51).
...
A subroutine entry representing a subroutine declaration that is not also a
definition does not have code address or range attributes.
```

We should just ignore those DIEs.
2025-06-13 14:40:27 +01:00
Jason Molenda
7730093596 Revert "[lldb] Don't create instance of SymbolFileDWARFDebugMap for non-Mach-O files (#139170)"
This reverts commit 3096f8768676bd64123270cc59b7cc904a72d875.

Reverting this commit because it depends on another PR
that was reverted, https://github.com/llvm/llvm-project/pull/142704

Both can be reapplied once we find a correct fix for that.
2025-06-05 17:47:04 -07:00
royitaqi
3096f87686
[lldb] Don't create instance of SymbolFileDWARFDebugMap for non-Mach-O files (#139170)
# Change

`SymbolFileDWARFDebugMap::CreateInstance()` will return `nullptr` if the
file is not a Mach-O.


# Benefit

This may improve **Linux** debugger launch time by skipping the creation
of `SymbolFileDWARFDebugMap` during the [`SymbolFile::FindPlugin()`
call](https://fburl.com/hi1w8dil), which loops through a list of
`SymbolFile` plugins and tries to find the one that provides the best
abilities. If the `SymbolFileDWARFDebugMap` is created during this loop,
it will load the symbol table of the file in question and loop through
all the compile units in the debug map (the OSO entries) to calculate
the abilities.


# Tests

See PR.
2025-06-05 07:38:39 -07:00