[Lldb-commits] [lldb] Revert "[LLDB] DebugInfoD tests: attempt to fix Fuchsia build" (PR #98101)

2024-07-08 Thread Greg Clayton via lldb-commits

https://github.com/clayborg closed 
https://github.com/llvm/llvm-project/pull/98101
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] Revert "[LLDB] DebugInfoD tests: attempt to fix Fuchsia build" (PR #98101)

2024-07-08 Thread Greg Clayton via lldb-commits

https://github.com/clayborg approved this pull request.


https://github.com/llvm/llvm-project/pull/98101
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [LLDB] DebugInfoD tests: attempt to fix Fuchsia build (PR #96802)

2024-07-08 Thread Greg Clayton via lldb-commits

https://github.com/clayborg closed 
https://github.com/llvm/llvm-project/pull/96802
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] Fix the test to deal with non-deterministic output. (PR #96800)

2024-06-28 Thread Greg Clayton via lldb-commits

https://github.com/clayborg closed 
https://github.com/llvm/llvm-project/pull/96800
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb/DWARF] Unique enums parsed from declarations (PR #96751)

2024-06-26 Thread Greg Clayton via lldb-commits

https://github.com/clayborg approved this pull request.


https://github.com/llvm/llvm-project/pull/96751
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [llvm] Add support for using foreign type units in .debug_names. (PR #87740)

2024-06-26 Thread Greg Clayton via lldb-commits

clayborg wrote:

Here is a PR to fix the flaky test:

https://github.com/llvm/llvm-project/pull/96800


https://github.com/llvm/llvm-project/pull/87740
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] Fix the test to deal with non-deterministic output. (PR #96800)

2024-06-26 Thread Greg Clayton via lldb-commits

https://github.com/clayborg created 
https://github.com/llvm/llvm-project/pull/96800

When we check for the "struct CustomType" in the NODWP, we can just make sure 
that we have both types showing up, the next tests will validate the types are 
correct. Also added a "-DAG" to the integer and float types. This should fix 
the flakiness in this test.

>From a874efd2b746c1f4fcf426f7d2426d28230e7714 Mon Sep 17 00:00:00 2001
From: Greg Clayton 
Date: Wed, 26 Jun 2024 10:12:05 -0700
Subject: [PATCH] Fix the test to deal with non-deterministic output.

When we check for the "struct CustomType" in the NODWP, we can just make sure 
that we have both types showing up, the next tests will validate the types are 
correct. Also added a "-DAG" to the integer and float types. This should fix 
the flakiness in this test.
---
 .../DWARF/x86/dwp-foreign-type-units.cpp  | 22 +--
 1 file changed, 6 insertions(+), 16 deletions(-)

diff --git a/lldb/test/Shell/SymbolFile/DWARF/x86/dwp-foreign-type-units.cpp 
b/lldb/test/Shell/SymbolFile/DWARF/x86/dwp-foreign-type-units.cpp
index 8dd5a5472ed4c..4df1b33dd7d91 100644
--- a/lldb/test/Shell/SymbolFile/DWARF/x86/dwp-foreign-type-units.cpp
+++ b/lldb/test/Shell/SymbolFile/DWARF/x86/dwp-foreign-type-units.cpp
@@ -30,24 +30,14 @@
 // RUN:   -o "type lookup CustomType" \
 // RUN:   -b %t | FileCheck %s --check-prefix=NODWP
 // NODWP: (lldb) type lookup IntegerType
-// NODWP-NEXT: int
-// NODWP-NEXT: unsigned int
+// NODWP-DAG: int
+// NODWP-DAG: unsigned int
 // NODWP: (lldb) type lookup FloatType
-// NODWP-NEXT: double
-// NODWP-NEXT: float
+// NODWP-DAG: double
+// NODWP-DAG: float
 // NODWP: (lldb) type lookup CustomType
-// NODWP-NEXT: struct CustomType {
-// NODWP-NEXT: typedef int IntegerType;
-// NODWP-NEXT: typedef double FloatType;
-// NODWP-NEXT: CustomType::IntegerType x;
-// NODWP-NEXT: CustomType::FloatType y;
-// NODWP-NEXT: }
-// NODWP-NEXT: struct CustomType {
-// NODWP-NEXT: typedef unsigned int IntegerType;
-// NODWP-NEXT: typedef float FloatType;
-// NODWP-NEXT: CustomType::IntegerType x;
-// NODWP-NEXT: CustomType::FloatType y;
-// NODWP-NEXT: }
+// NODWP: struct CustomType {
+// NODWP: struct CustomType {
 
 // Check when we make the .dwp file with %t.main.dwo first so it will
 // pick the type unit from %t.main.dwo. Verify we find only the types from

___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] Add format eFormatEnumWithValues to ensure raw enum value is always shown (PR #90059)

2024-06-26 Thread Greg Clayton via lldb-commits

clayborg wrote:

Sorry for the delay, I am still wondering if we just want to have the value 
objects for enums return the text name as the value, and have the summary show 
the value as an appropriate integer if the format is eFormatEnum. When you 
display registers bitfields do you have a ValueObject? If so we can modify the 
`ValueObject::GetSummary()` to return the integer value, but only if we have 
the format set to `eFormatEnum`. The output for variables would be similar to 
what your tests expect, but we would just modify the summary string that we 
return and then we don't need the new format. 

One reason I like this way of doing things is if you call "valobj.GetValue()", 
and the format is set the enum with value, we will get "foo (1)" as the value 
back from the value object. I would rather call `valobj.GetValue()` and get 
`"foo"` and then call `valojb.GetSummary()` and get `"1"`, or of course you can 
always just call `valobj.GetValueAsUnsigned(...)` or 
`valobj.GetValueAsSigned(...)`. If we have special display code for the 
register bitfields, they can call these APIs when displaying register by 
default?

https://github.com/llvm/llvm-project/pull/90059
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] Use `Address` to setup breakpoint (PR #94794)

2024-06-26 Thread Greg Clayton via lldb-commits

https://github.com/clayborg edited 
https://github.com/llvm/llvm-project/pull/94794
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] Use `Address` to setup breakpoint (PR #94794)

2024-06-26 Thread Greg Clayton via lldb-commits


@@ -90,17 +90,9 @@ void InstrumentationRuntimeASanLibsanitizers::Activate() {
   if (!process_sp)
 return;
 
-  lldb::ModuleSP module_sp = GetRuntimeModuleSP();
-
   Breakpoint *breakpoint = ReportRetriever::SetupBreakpoint(
-  module_sp, process_sp, ConstString("sanitizers_address_on_report"));
-
-  if (!breakpoint) {
-breakpoint = ReportRetriever::SetupBreakpoint(
-module_sp, process_sp,
-ConstString("_Z22raise_sanitizers_error23sanitizer_error_context"));
-  }
-
+  GetRuntimeModuleSP(), process_sp,
+  ConstString("sanitizers_address_on_report"));

clayborg wrote:

This doesn't look right. Is this left over from the older code? Remove this?

https://github.com/llvm/llvm-project/pull/94794
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] Use `Address` to setup breakpoint (PR #94794)

2024-06-26 Thread Greg Clayton via lldb-commits

https://github.com/clayborg requested changes to this pull request.


https://github.com/llvm/llvm-project/pull/94794
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] Fix string truncation method when substring is the prefix of string (NFC) (PR #94785)

2024-06-26 Thread Greg Clayton via lldb-commits

https://github.com/clayborg requested changes to this pull request.


https://github.com/llvm/llvm-project/pull/94785
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] Fix string truncation method when substring is the prefix of string (NFC) (PR #94785)

2024-06-26 Thread Greg Clayton via lldb-commits


@@ -287,7 +287,7 @@ Status PlatformAndroid::DownloadModuleSlice(const FileSpec 
_file_spec,
   static constexpr llvm::StringLiteral k_zip_separator("!/");
   size_t pos = source_file.find(k_zip_separator);
   if (pos != std::string::npos)
-source_file = source_file.substr(0, pos);
+source_file = source_file.resize(0, pos);

clayborg wrote:

`std::string::resize()` returns `void` so this won't even compile. The right 
fix is:
```
source_file.resize(pos);
```


https://github.com/llvm/llvm-project/pull/94785
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] Fix string truncation method when substring is the prefix of string (NFC) (PR #94785)

2024-06-26 Thread Greg Clayton via lldb-commits

https://github.com/clayborg edited 
https://github.com/llvm/llvm-project/pull/94785
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb][API] Add Find(Ranges)InMemory() to Process SB API (PR #96569)

2024-06-24 Thread Greg Clayton via lldb-commits

https://github.com/clayborg approved this pull request.


https://github.com/llvm/llvm-project/pull/96569
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] Fix tests for FindInMemory SB API introduced in #95007. (PR #96565)

2024-06-24 Thread Greg Clayton via lldb-commits

https://github.com/clayborg commented:

Just add a description to what this test had wrong, what is fixed and any other 
needed details and this should be good to go

https://github.com/llvm/llvm-project/pull/96565
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [llvm] [LLDB][Minidump] Add 64b support to LLDB's minidump file builder. (PR #95312)

2024-06-24 Thread Greg Clayton via lldb-commits

https://github.com/clayborg closed 
https://github.com/llvm/llvm-project/pull/95312
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [llvm] Add support for using foreign type units in .debug_names. (PR #87740)

2024-06-24 Thread Greg Clayton via lldb-commits

clayborg wrote:

An extra character snuck in and messed with the buildbots, fixed with:
```
commit fc066ca1c32b4aef549f3e371dc70589804aba0f (HEAD -> main, origin/main, 
origin/HEAD)
Author: Greg Clayton 
Date:   Mon Jun 24 10:15:55 2024 -0700

Fix buildbots for https://github.com/llvm/llvm-project/pull/87740
```

https://github.com/llvm/llvm-project/pull/87740
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] fc066ca - Fix buildbots for https://github.com/llvm/llvm-project/pull/87740

2024-06-24 Thread Greg Clayton via lldb-commits

Author: Greg Clayton
Date: 2024-06-24T10:16:39-07:00
New Revision: fc066ca1c32b4aef549f3e371dc70589804aba0f

URL: 
https://github.com/llvm/llvm-project/commit/fc066ca1c32b4aef549f3e371dc70589804aba0f
DIFF: 
https://github.com/llvm/llvm-project/commit/fc066ca1c32b4aef549f3e371dc70589804aba0f.diff

LOG: Fix buildbots for https://github.com/llvm/llvm-project/pull/87740

Added: 


Modified: 
lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp

Removed: 




diff  --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp 
b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
index bd81618ac914d..70aa4b9e1f203 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
@@ -1746,7 +1746,7 @@ SymbolFileDWARF 
*SymbolFileDWARF::GetDIERefSymbolFile(const DIERef _ref) {
 
   if (file_index) {
   // We have a SymbolFileDWARFDebugMap, so let it find the right file
-\if (SymbolFileDWARFDebugMap *debug_map = GetDebugMapSymfile())
+if (SymbolFileDWARFDebugMap *debug_map = GetDebugMapSymfile())
   return debug_map->GetSymbolFileByOSOIndex(*file_index);
 
 // Handle the .dwp file case correctly



___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [llvm] Add support for using foreign type units in .debug_names. (PR #87740)

2024-06-24 Thread Greg Clayton via lldb-commits

https://github.com/clayborg closed 
https://github.com/llvm/llvm-project/pull/87740
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [llvm] Add support for using foreign type units in .debug_names. (PR #87740)

2024-06-24 Thread Greg Clayton via lldb-commits

https://github.com/clayborg updated 
https://github.com/llvm/llvm-project/pull/87740

>From 3f99b41eac0e04e15bdb99bea2ee75703936ea00 Mon Sep 17 00:00:00 2001
From: Greg Clayton 
Date: Sat, 30 Mar 2024 10:50:34 -0700
Subject: [PATCH 01/12] Add support for using foreign type units in
 .debug_names.

This patch adds support for the new foreign type unit support in .debug_names. 
Features include:
- don't manually index foreign TUs if we have info for them
- only use the type unit entries that match the .dwo files when we have a .dwp 
file
- fix crashers that happen due to PeekDIEName() using wrong offsets
---
 .../SymbolFile/DWARF/DWARFDebugInfo.cpp   | 18 
 .../Plugins/SymbolFile/DWARF/DWARFDebugInfo.h |  2 +
 .../SymbolFile/DWARF/DebugNamesDWARFIndex.cpp | 65 -
 .../SymbolFile/DWARF/DebugNamesDWARFIndex.h   |  6 +-
 .../SymbolFile/DWARF/ManualDWARFIndex.cpp |  6 +-
 .../SymbolFile/DWARF/ManualDWARFIndex.h   |  7 +-
 .../SymbolFile/DWARF/SymbolFileDWARF.cpp  | 66 --
 .../SymbolFile/DWARF/SymbolFileDWARF.h|  9 ++
 .../DWARF/x86/dwp-foreign-type-units.cpp  | 91 +++
 .../DebugInfo/DWARF/DWARFAcceleratorTable.h   | 11 +++
 .../DebugInfo/DWARF/DWARFAcceleratorTable.cpp | 13 +++
 11 files changed, 257 insertions(+), 37 deletions(-)
 create mode 100644 
lldb/test/Shell/SymbolFile/DWARF/x86/dwp-foreign-type-units.cpp

diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp 
b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp
index c37cc91e08ed12..056c6d4b0605f8 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp
@@ -222,6 +222,20 @@ DWARFUnit *DWARFDebugInfo::GetUnitAtOffset(DIERef::Section 
section,
   return result;
 }
 
+DWARFUnit *DWARFDebugInfo::GetUnit(const DIERef _ref) {
+  // Make sure we get the correct SymbolFileDWARF from the DIERef before
+  // asking for information from a debug info object. We might start with the
+  // DWARFDebugInfo for the main executable in a split DWARF and the DIERef
+  // might be pointing to a specific .dwo file or to the .dwp file. So this
+  // makes sure we get the right SymbolFileDWARF instance before finding the
+  // DWARFUnit that contains the offset. If we just use this object to do the
+  // search, we might be using the wrong .debug_info section from the wrong
+  // file with an offset meant for a different section.
+  SymbolFileDWARF *dwarf = m_dwarf.GetDIERefSymbolFile(die_ref);
+  return dwarf->DebugInfo().GetUnitContainingDIEOffset(die_ref.section(),
+   die_ref.die_offset());
+}
+
 DWARFUnit *
 DWARFDebugInfo::GetUnitContainingDIEOffset(DIERef::Section section,
dw_offset_t die_offset) {
@@ -232,6 +246,10 @@ DWARFDebugInfo::GetUnitContainingDIEOffset(DIERef::Section 
section,
   return result;
 }
 
+const std::shared_ptr DWARFDebugInfo::GetDwpSymbolFile() {
+  return m_dwarf.GetDwpSymbolFile();
+}
+
 DWARFTypeUnit *DWARFDebugInfo::GetTypeUnitForHash(uint64_t hash) {
   auto pos = llvm::lower_bound(m_type_hash_to_unit_index,
std::make_pair(hash, 0u), llvm::less_first());
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.h 
b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.h
index 4706b55d38ea98..4d4555a3382529 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.h
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.h
@@ -52,6 +52,8 @@ class DWARFDebugInfo {
 
   const DWARFDebugAranges ();
 
+  const std::shared_ptr GetDwpSymbolFile();
+
 protected:
   typedef std::vector UnitColl;
 
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp 
b/lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp
index 1d17f20670eed4..d815d345b08ee7 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp
@@ -34,6 +34,18 @@ DebugNamesDWARFIndex::Create(Module , 
DWARFDataExtractor debug_names,
   module, std::move(index_up), debug_names, debug_str, dwarf));
 }
 
+
+llvm::DenseSet
+DebugNamesDWARFIndex::GetTypeUnitSigs(const DebugNames _names) {
+  llvm::DenseSet result;
+  for (const DebugNames::NameIndex  : debug_names) {
+const uint32_t num_tus = ni.getForeignTUCount();
+for (uint32_t tu = 0; tu < num_tus; ++tu)
+  result.insert(ni.getForeignTUSignature(tu));
+  }
+  return result;
+}
+
 llvm::DenseSet
 DebugNamesDWARFIndex::GetUnits(const DebugNames _names) {
   llvm::DenseSet result;
@@ -48,17 +60,22 @@ DebugNamesDWARFIndex::GetUnits(const DebugNames 
_names) {
   return result;
 }
 
+DWARFTypeUnit *
+DebugNamesDWARFIndex::GetForeignTypeUnit(const DebugNames::Entry ) const 
{
+  std::optional type_sig = entry.getForeignTUTypeSignature();
+  if (type_sig)
+if (auto dwp_sp = m_debug_info.GetDwpSymbolFile())
+  

[Lldb-commits] [lldb] [lldb][API] Add Find(Ranges)InMemory() to Process SB API (PR #95007)

2024-06-23 Thread Greg Clayton via lldb-commits

https://github.com/clayborg approved this pull request.


https://github.com/llvm/llvm-project/pull/95007
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb][API] Add Find(Ranges)InMemory() to Process SB API (PR #95007)

2024-06-21 Thread Greg Clayton via lldb-commits


@@ -2007,6 +2007,135 @@ size_t Process::ReadMemory(addr_t addr, void *buf, 
size_t size, Status ) {
   }
 }
 
+void Process::DoFindInMemory(lldb::addr_t start_addr, lldb::addr_t end_addr,
+ const uint8_t *buf, size_t size,
+ AddressRanges , size_t alignment,
+ size_t max_matches) {
+  // Inputs are already validated in FindInMemory() functions.
+  assert(buf != nullptr);
+  assert(size > 0);
+  assert(alignment > 0);
+  assert(max_matches > 0);
+  assert(start_addr != LLDB_INVALID_ADDRESS);
+  assert(end_addr != LLDB_INVALID_ADDRESS);
+  assert(start_addr < end_addr);
+
+  lldb::addr_t start = start_addr;
+  if (alignment > 1) {
+// Align to an address alignment boundary
+const uint64_t align_offset = start % alignment;
+if (align_offset > 0)
+  start += alignment - align_offset;
+  }
+  while (matches.size() < max_matches && (start + size) < end_addr) {
+const lldb::addr_t found_addr = FindInMemory(start, end_addr, buf, size);
+if (found_addr == LLDB_INVALID_ADDRESS)
+  break;
+
+if (found_addr % alignment) {

clayborg wrote:

Add a comment about why we need to check the alignment here:
```
// We need to check the alignment because the FindInMemory uses a special 
algorithm to efficiently search mememory but doesn't support alignment.
```

https://github.com/llvm/llvm-project/pull/95007
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb][API] Add Find(Ranges)InMemory() to Process SB API (PR #95007)

2024-06-21 Thread Greg Clayton via lldb-commits


@@ -2007,6 +2007,135 @@ size_t Process::ReadMemory(addr_t addr, void *buf, 
size_t size, Status ) {
   }
 }
 
+void Process::DoFindInMemory(lldb::addr_t start_addr, lldb::addr_t end_addr,
+ const uint8_t *buf, size_t size,
+ AddressRanges , size_t alignment,
+ size_t max_matches) {
+  // Inputs are already validated in FindInMemory() functions.
+  assert(buf != nullptr);
+  assert(size > 0);
+  assert(alignment > 0);
+  assert(max_matches > 0);
+  assert(start_addr != LLDB_INVALID_ADDRESS);
+  assert(end_addr != LLDB_INVALID_ADDRESS);
+  assert(start_addr < end_addr);
+
+  lldb::addr_t start = start_addr;
+  if (alignment > 1) {
+// Align to an address alignment boundary
+const uint64_t align_offset = start % alignment;
+if (align_offset > 0)
+  start += alignment - align_offset;
+  }
+  while (matches.size() < max_matches && (start + size) < end_addr) {
+const lldb::addr_t found_addr = FindInMemory(start, end_addr, buf, size);
+if (found_addr == LLDB_INVALID_ADDRESS)
+  break;
+
+if (found_addr % alignment) {
+  ++start;

clayborg wrote:

No sense in just incrementing by 1, lets increment by an aligned value.
```
start = llvm::alignTo(start+1, alignment);
```

https://github.com/llvm/llvm-project/pull/95007
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb][API] Add Find(Ranges)InMemory() to Process SB API (PR #95007)

2024-06-21 Thread Greg Clayton via lldb-commits


@@ -2007,6 +2007,135 @@ size_t Process::ReadMemory(addr_t addr, void *buf, 
size_t size, Status ) {
   }
 }
 
+void Process::DoFindInMemory(lldb::addr_t start_addr, lldb::addr_t end_addr,
+ const uint8_t *buf, size_t size,
+ AddressRanges , size_t alignment,
+ size_t max_matches) {
+  // Inputs are already validated in FindInMemory() functions.
+  assert(buf != nullptr);
+  assert(size > 0);
+  assert(alignment > 0);
+  assert(max_matches > 0);
+  assert(start_addr != LLDB_INVALID_ADDRESS);
+  assert(end_addr != LLDB_INVALID_ADDRESS);
+  assert(start_addr < end_addr);
+
+  lldb::addr_t start = start_addr;
+  if (alignment > 1) {
+// Align to an address alignment boundary
+const uint64_t align_offset = start % alignment;
+if (align_offset > 0)
+  start += alignment - align_offset;
+  }
+  while (matches.size() < max_matches && (start + size) < end_addr) {
+const lldb::addr_t found_addr = FindInMemory(start, end_addr, buf, size);
+if (found_addr == LLDB_INVALID_ADDRESS)
+  break;
+
+if (found_addr % alignment) {
+  ++start;
+  continue;
+}
+
+matches.emplace_back(found_addr, size);
+start = found_addr + alignment;
+  }
+}
+
+AddressRanges Process::FindRangesInMemory(const uint8_t *buf, uint64_t size,
+  const AddressRanges ,
+  size_t alignment, size_t max_matches,
+  Status ) {
+  AddressRanges matches;
+  if (buf == nullptr) {
+error.SetErrorString("buffer is null");
+return matches;
+  }
+  if (size == 0) {
+error.SetErrorString("buffer size is zero");
+return matches;
+  }
+  if (ranges.empty()) {
+error.SetErrorString("empty ranges");
+return matches;
+  }
+  if (alignment == 0) {
+error.SetErrorString("alignment must be greater than zero");
+return matches;
+  }
+  if (max_matches == 0) {
+error.SetErrorString("max_matches must be greater than zero");
+return matches;
+  }
+
+  int resolved_ranges = 0;
+  Target  = GetTarget();
+  for (size_t i = 0; i < ranges.size(); ++i) {
+if (matches.size() >= max_matches) {
+  break;
+}
+const AddressRange  = ranges[i];
+if (range.IsValid() == false) {
+  continue;
+}
+
+const lldb::addr_t start_addr =
+range.GetBaseAddress().GetLoadAddress();
+if (start_addr == LLDB_INVALID_ADDRESS) {
+  continue;
+}
+++resolved_ranges;
+const lldb::addr_t end_addr = start_addr + range.GetByteSize();
+DoFindInMemory(start_addr, end_addr, buf, size, matches, alignment,
+   max_matches);
+  }
+
+  if (resolved_ranges > 0) {
+error.Clear();
+  } else {
+error.SetErrorString("unable to resolve any ranges");
+  }

clayborg wrote:

remove single if/else statement '{}' per llvm coding guidelines

https://github.com/llvm/llvm-project/pull/95007
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb][API] Add Find(Ranges)InMemory() to Process SB API (PR #95007)

2024-06-21 Thread Greg Clayton via lldb-commits


@@ -2007,6 +2007,135 @@ size_t Process::ReadMemory(addr_t addr, void *buf, 
size_t size, Status ) {
   }
 }
 
+void Process::DoFindInMemory(lldb::addr_t start_addr, lldb::addr_t end_addr,
+ const uint8_t *buf, size_t size,
+ AddressRanges , size_t alignment,
+ size_t max_matches) {
+  // Inputs are already validated in FindInMemory() functions.
+  assert(buf != nullptr);
+  assert(size > 0);
+  assert(alignment > 0);
+  assert(max_matches > 0);
+  assert(start_addr != LLDB_INVALID_ADDRESS);
+  assert(end_addr != LLDB_INVALID_ADDRESS);
+  assert(start_addr < end_addr);
+
+  lldb::addr_t start = start_addr;
+  if (alignment > 1) {
+// Align to an address alignment boundary
+const uint64_t align_offset = start % alignment;
+if (align_offset > 0)
+  start += alignment - align_offset;
+  }
+  while (matches.size() < max_matches && (start + size) < end_addr) {
+const lldb::addr_t found_addr = FindInMemory(start, end_addr, buf, size);
+if (found_addr == LLDB_INVALID_ADDRESS)
+  break;
+
+if (found_addr % alignment) {
+  ++start;
+  continue;
+}
+
+matches.emplace_back(found_addr, size);
+start = found_addr + alignment;
+  }
+}
+
+AddressRanges Process::FindRangesInMemory(const uint8_t *buf, uint64_t size,
+  const AddressRanges ,
+  size_t alignment, size_t max_matches,
+  Status ) {
+  AddressRanges matches;
+  if (buf == nullptr) {
+error.SetErrorString("buffer is null");
+return matches;
+  }
+  if (size == 0) {
+error.SetErrorString("buffer size is zero");
+return matches;
+  }
+  if (ranges.empty()) {
+error.SetErrorString("empty ranges");
+return matches;
+  }
+  if (alignment == 0) {
+error.SetErrorString("alignment must be greater than zero");
+return matches;
+  }
+  if (max_matches == 0) {
+error.SetErrorString("max_matches must be greater than zero");
+return matches;
+  }
+
+  int resolved_ranges = 0;
+  Target  = GetTarget();
+  for (size_t i = 0; i < ranges.size(); ++i) {
+if (matches.size() >= max_matches) {
+  break;
+}
+const AddressRange  = ranges[i];
+if (range.IsValid() == false) {
+  continue;
+}
+
+const lldb::addr_t start_addr =
+range.GetBaseAddress().GetLoadAddress();
+if (start_addr == LLDB_INVALID_ADDRESS) {
+  continue;
+}

clayborg wrote:

remove single if statement '{}' per llvm coding guidelines

https://github.com/llvm/llvm-project/pull/95007
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb][API] Add Find(Ranges)InMemory() to Process SB API (PR #95007)

2024-06-21 Thread Greg Clayton via lldb-commits


@@ -2007,6 +2007,135 @@ size_t Process::ReadMemory(addr_t addr, void *buf, 
size_t size, Status ) {
   }
 }
 
+void Process::DoFindInMemory(lldb::addr_t start_addr, lldb::addr_t end_addr,
+ const uint8_t *buf, size_t size,
+ AddressRanges , size_t alignment,
+ size_t max_matches) {
+  // Inputs are already validated in FindInMemory() functions.
+  assert(buf != nullptr);
+  assert(size > 0);
+  assert(alignment > 0);
+  assert(max_matches > 0);
+  assert(start_addr != LLDB_INVALID_ADDRESS);
+  assert(end_addr != LLDB_INVALID_ADDRESS);
+  assert(start_addr < end_addr);
+
+  lldb::addr_t start = start_addr;
+  if (alignment > 1) {
+// Align to an address alignment boundary
+const uint64_t align_offset = start % alignment;
+if (align_offset > 0)
+  start += alignment - align_offset;
+  }
+  while (matches.size() < max_matches && (start + size) < end_addr) {
+const lldb::addr_t found_addr = FindInMemory(start, end_addr, buf, size);
+if (found_addr == LLDB_INVALID_ADDRESS)
+  break;
+
+if (found_addr % alignment) {
+  ++start;
+  continue;
+}
+
+matches.emplace_back(found_addr, size);
+start = found_addr + alignment;
+  }
+}
+
+AddressRanges Process::FindRangesInMemory(const uint8_t *buf, uint64_t size,
+  const AddressRanges ,
+  size_t alignment, size_t max_matches,
+  Status ) {
+  AddressRanges matches;
+  if (buf == nullptr) {
+error.SetErrorString("buffer is null");
+return matches;
+  }
+  if (size == 0) {
+error.SetErrorString("buffer size is zero");
+return matches;
+  }
+  if (ranges.empty()) {
+error.SetErrorString("empty ranges");
+return matches;
+  }
+  if (alignment == 0) {
+error.SetErrorString("alignment must be greater than zero");
+return matches;
+  }
+  if (max_matches == 0) {
+error.SetErrorString("max_matches must be greater than zero");
+return matches;
+  }
+
+  int resolved_ranges = 0;
+  Target  = GetTarget();
+  for (size_t i = 0; i < ranges.size(); ++i) {
+if (matches.size() >= max_matches) {
+  break;
+}
+const AddressRange  = ranges[i];
+if (range.IsValid() == false) {
+  continue;
+}

clayborg wrote:

remove single if statement '{}' per llvm coding guidelines

https://github.com/llvm/llvm-project/pull/95007
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb][API] Add Find(Ranges)InMemory() to Process SB API (PR #95007)

2024-06-21 Thread Greg Clayton via lldb-commits


@@ -2007,6 +2007,135 @@ size_t Process::ReadMemory(addr_t addr, void *buf, 
size_t size, Status ) {
   }
 }
 
+void Process::DoFindInMemory(lldb::addr_t start_addr, lldb::addr_t end_addr,
+ const uint8_t *buf, size_t size,
+ AddressRanges , size_t alignment,
+ size_t max_matches) {
+  // Inputs are already validated in FindInMemory() functions.
+  assert(buf != nullptr);
+  assert(size > 0);
+  assert(alignment > 0);
+  assert(max_matches > 0);
+  assert(start_addr != LLDB_INVALID_ADDRESS);
+  assert(end_addr != LLDB_INVALID_ADDRESS);
+  assert(start_addr < end_addr);
+
+  lldb::addr_t start = start_addr;
+  if (alignment > 1) {
+// Align to an address alignment boundary
+const uint64_t align_offset = start % alignment;
+if (align_offset > 0)
+  start += alignment - align_offset;
+  }

clayborg wrote:

All these lines can be:
```
lldb::addr_t start = llvm::alignTo(start_addr, alignment);
```

https://github.com/llvm/llvm-project/pull/95007
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb][API] Add Find(Ranges)InMemory() to Process SB API (PR #95007)

2024-06-21 Thread Greg Clayton via lldb-commits


@@ -2007,6 +2007,135 @@ size_t Process::ReadMemory(addr_t addr, void *buf, 
size_t size, Status ) {
   }
 }
 
+void Process::DoFindInMemory(lldb::addr_t start_addr, lldb::addr_t end_addr,
+ const uint8_t *buf, size_t size,
+ AddressRanges , size_t alignment,
+ size_t max_matches) {
+  // Inputs are already validated in FindInMemory() functions.
+  assert(buf != nullptr);
+  assert(size > 0);
+  assert(alignment > 0);
+  assert(max_matches > 0);
+  assert(start_addr != LLDB_INVALID_ADDRESS);
+  assert(end_addr != LLDB_INVALID_ADDRESS);
+  assert(start_addr < end_addr);
+
+  lldb::addr_t start = start_addr;
+  if (alignment > 1) {
+// Align to an address alignment boundary
+const uint64_t align_offset = start % alignment;
+if (align_offset > 0)
+  start += alignment - align_offset;
+  }
+  while (matches.size() < max_matches && (start + size) < end_addr) {
+const lldb::addr_t found_addr = FindInMemory(start, end_addr, buf, size);
+if (found_addr == LLDB_INVALID_ADDRESS)
+  break;
+
+if (found_addr % alignment) {
+  ++start;
+  continue;
+}
+
+matches.emplace_back(found_addr, size);
+start = found_addr + alignment;
+  }
+}
+
+AddressRanges Process::FindRangesInMemory(const uint8_t *buf, uint64_t size,
+  const AddressRanges ,
+  size_t alignment, size_t max_matches,
+  Status ) {
+  AddressRanges matches;
+  if (buf == nullptr) {
+error.SetErrorString("buffer is null");
+return matches;
+  }
+  if (size == 0) {
+error.SetErrorString("buffer size is zero");
+return matches;
+  }
+  if (ranges.empty()) {
+error.SetErrorString("empty ranges");
+return matches;
+  }
+  if (alignment == 0) {
+error.SetErrorString("alignment must be greater than zero");
+return matches;
+  }
+  if (max_matches == 0) {
+error.SetErrorString("max_matches must be greater than zero");
+return matches;
+  }
+
+  int resolved_ranges = 0;
+  Target  = GetTarget();
+  for (size_t i = 0; i < ranges.size(); ++i) {
+if (matches.size() >= max_matches) {
+  break;
+}

clayborg wrote:

remove single if statement '{}' per llvm coding guidelines

https://github.com/llvm/llvm-project/pull/95007
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [llvm] Add support for using foreign type units in .debug_names. (PR #87740)

2024-06-21 Thread Greg Clayton via lldb-commits

clayborg wrote:

All issues resolved except the change of `GetDIERefSymbolFile`. Let me know if 
you agree with my comments, or want a 
`GetSymbolFileByFileIndex(std::optional file_idx)`.

https://github.com/llvm/llvm-project/pull/87740
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [llvm] Add support for using foreign type units in .debug_names. (PR #87740)

2024-06-21 Thread Greg Clayton via lldb-commits


@@ -1727,45 +1727,61 @@ lldb::ModuleSP 
SymbolFileDWARF::GetExternalModule(ConstString name) {
   return pos->second;
 }
 
-DWARFDIE
-SymbolFileDWARF::GetDIE(const DIERef _ref) {
-  // This method can be called without going through the symbol vendor so we
-  // need to lock the module.
-  std::lock_guard guard(GetModuleMutex());
-
-  SymbolFileDWARF *symbol_file = nullptr;
-
+SymbolFileDWARF *SymbolFileDWARF::GetDIERefSymbolFile(const DIERef _ref) {
   // Anytime we get a "lldb::user_id_t" from an lldb_private::SymbolFile API we
   // must make sure we use the correct DWARF file when resolving things. On
   // MacOSX, when using SymbolFileDWARFDebugMap, we will use multiple
   // SymbolFileDWARF classes, one for each .o file. We can often end up with
   // references to other DWARF objects and we must be ready to receive a
   // "lldb::user_id_t" that specifies a DIE from another SymbolFileDWARF
   // instance.
+
   std::optional file_index = die_ref.file_index();
+
+  // If the file index matches, then we have the right SymbolFileDWARF already.
+  // This will work for both .dwo file and DWARF in .o files for mac. Also if
+  // both the file indexes are invalid, then we have a match.
+  if (GetFileIndex() == file_index)
+return this;
+
+  // If we are currently in a .dwo file and our file index doesn't match we 
need
+  // to let the base symbol file handle this.
+  SymbolFileDWARFDwo *dwo = llvm::dyn_cast_or_null(this);
+  if (dwo)
+return dwo->GetDIERefSymbolFile(die_ref);
+
   if (file_index) {
-if (SymbolFileDWARFDebugMap *debug_map = GetDebugMapSymfile()) {
-  symbol_file = debug_map->GetSymbolFileByOSOIndex(*file_index); // OSO 
case
-  if (symbol_file)
-return symbol_file->DebugInfo().GetDIE(die_ref.section(),
-   die_ref.die_offset());
-  return DWARFDIE();
+SymbolFileDWARFDebugMap *debug_map = GetDebugMapSymfile();
+if (debug_map) {
+  // We have a SymbolFileDWARFDebugMap, so let it find the right file
+  return debug_map->GetSymbolFileByOSOIndex(*file_index);
+} else {
+  // Handle the .dwp file case correctly
+  if (*file_index == DIERef::k_file_index_mask)
+return GetDwpSymbolFile().get(); // DWP case
+
+  // Handle the .dwo file case correctly
+  return DebugInfo()
+  .GetUnitAtIndex(*die_ref.file_index())
+  ->GetDwoSymbolFile(); // DWO case
 }
+  }
+  return this;
+}
 
-if (*file_index == DIERef::k_file_index_mask)
-  symbol_file = GetDwpSymbolFile().get(); // DWP case
-else
-  symbol_file = this->DebugInfo()
-.GetUnitAtIndex(*die_ref.file_index())
-->GetDwoSymbolFile(); // DWO case
-  } else if (die_ref.die_offset() == DW_INVALID_OFFSET) {
+DWARFDIE
+SymbolFileDWARF::GetDIE(const DIERef _ref) {
+  if (die_ref.die_offset() == DW_INVALID_OFFSET)
 return DWARFDIE();
-  }
 
+  // This method can be called without going through the symbol vendor so we
+  // need to lock the module.
+  std::lock_guard guard(GetModuleMutex());
+  SymbolFileDWARF *symbol_file = GetDIERefSymbolFile(die_ref);

clayborg wrote:

It only uses the file index component, but that component might not be set in 
the `DIERef` object and if it isn't, it returns the current SymbolFileDWARF 
object. We can make a function like:
```
SymbolFileDWARF *GetSymbolFileByFileIndex(std::optional file_index);
```
The file index only makes sense if it comes from a DIERef object as it 
understands the value and knows the magic value for the .dwp file, so the above 
API is much less clear as who else knows what a file index is and would 
actaully know to ask for the symbol file using such an index? Seems less clear 
to me than the existing API. Let me know if feel we should still change this

https://github.com/llvm/llvm-project/pull/87740
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [llvm] Add support for using foreign type units in .debug_names. (PR #87740)

2024-06-21 Thread Greg Clayton via lldb-commits

https://github.com/clayborg updated 
https://github.com/llvm/llvm-project/pull/87740

>From badd915257bb192add91696e0b8530c057bd385f Mon Sep 17 00:00:00 2001
From: Greg Clayton 
Date: Sat, 30 Mar 2024 10:50:34 -0700
Subject: [PATCH 01/12] Add support for using foreign type units in
 .debug_names.

This patch adds support for the new foreign type unit support in .debug_names. 
Features include:
- don't manually index foreign TUs if we have info for them
- only use the type unit entries that match the .dwo files when we have a .dwp 
file
- fix crashers that happen due to PeekDIEName() using wrong offsets
---
 .../SymbolFile/DWARF/DWARFDebugInfo.cpp   | 18 
 .../Plugins/SymbolFile/DWARF/DWARFDebugInfo.h |  2 +
 .../SymbolFile/DWARF/DebugNamesDWARFIndex.cpp | 65 -
 .../SymbolFile/DWARF/DebugNamesDWARFIndex.h   |  6 +-
 .../SymbolFile/DWARF/ManualDWARFIndex.cpp |  6 +-
 .../SymbolFile/DWARF/ManualDWARFIndex.h   |  7 +-
 .../SymbolFile/DWARF/SymbolFileDWARF.cpp  | 66 --
 .../SymbolFile/DWARF/SymbolFileDWARF.h|  9 ++
 .../DWARF/x86/dwp-foreign-type-units.cpp  | 91 +++
 .../DebugInfo/DWARF/DWARFAcceleratorTable.h   | 11 +++
 .../DebugInfo/DWARF/DWARFAcceleratorTable.cpp | 13 +++
 11 files changed, 257 insertions(+), 37 deletions(-)
 create mode 100644 
lldb/test/Shell/SymbolFile/DWARF/x86/dwp-foreign-type-units.cpp

diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp 
b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp
index c37cc91e08ed1..056c6d4b0605f 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp
@@ -222,6 +222,20 @@ DWARFUnit *DWARFDebugInfo::GetUnitAtOffset(DIERef::Section 
section,
   return result;
 }
 
+DWARFUnit *DWARFDebugInfo::GetUnit(const DIERef _ref) {
+  // Make sure we get the correct SymbolFileDWARF from the DIERef before
+  // asking for information from a debug info object. We might start with the
+  // DWARFDebugInfo for the main executable in a split DWARF and the DIERef
+  // might be pointing to a specific .dwo file or to the .dwp file. So this
+  // makes sure we get the right SymbolFileDWARF instance before finding the
+  // DWARFUnit that contains the offset. If we just use this object to do the
+  // search, we might be using the wrong .debug_info section from the wrong
+  // file with an offset meant for a different section.
+  SymbolFileDWARF *dwarf = m_dwarf.GetDIERefSymbolFile(die_ref);
+  return dwarf->DebugInfo().GetUnitContainingDIEOffset(die_ref.section(),
+   die_ref.die_offset());
+}
+
 DWARFUnit *
 DWARFDebugInfo::GetUnitContainingDIEOffset(DIERef::Section section,
dw_offset_t die_offset) {
@@ -232,6 +246,10 @@ DWARFDebugInfo::GetUnitContainingDIEOffset(DIERef::Section 
section,
   return result;
 }
 
+const std::shared_ptr DWARFDebugInfo::GetDwpSymbolFile() {
+  return m_dwarf.GetDwpSymbolFile();
+}
+
 DWARFTypeUnit *DWARFDebugInfo::GetTypeUnitForHash(uint64_t hash) {
   auto pos = llvm::lower_bound(m_type_hash_to_unit_index,
std::make_pair(hash, 0u), llvm::less_first());
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.h 
b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.h
index 4706b55d38ea9..4d4555a338252 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.h
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.h
@@ -52,6 +52,8 @@ class DWARFDebugInfo {
 
   const DWARFDebugAranges ();
 
+  const std::shared_ptr GetDwpSymbolFile();
+
 protected:
   typedef std::vector UnitColl;
 
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp 
b/lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp
index 1d17f20670eed..d815d345b08ee 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp
@@ -34,6 +34,18 @@ DebugNamesDWARFIndex::Create(Module , 
DWARFDataExtractor debug_names,
   module, std::move(index_up), debug_names, debug_str, dwarf));
 }
 
+
+llvm::DenseSet
+DebugNamesDWARFIndex::GetTypeUnitSigs(const DebugNames _names) {
+  llvm::DenseSet result;
+  for (const DebugNames::NameIndex  : debug_names) {
+const uint32_t num_tus = ni.getForeignTUCount();
+for (uint32_t tu = 0; tu < num_tus; ++tu)
+  result.insert(ni.getForeignTUSignature(tu));
+  }
+  return result;
+}
+
 llvm::DenseSet
 DebugNamesDWARFIndex::GetUnits(const DebugNames _names) {
   llvm::DenseSet result;
@@ -48,17 +60,22 @@ DebugNamesDWARFIndex::GetUnits(const DebugNames 
_names) {
   return result;
 }
 
+DWARFTypeUnit *
+DebugNamesDWARFIndex::GetForeignTypeUnit(const DebugNames::Entry ) const 
{
+  std::optional type_sig = entry.getForeignTUTypeSignature();
+  if (type_sig)
+if (auto dwp_sp = m_debug_info.GetDwpSymbolFile())
+  return 

[Lldb-commits] [lldb] [llvm] Add support for using foreign type units in .debug_names. (PR #96243)

2024-06-20 Thread Greg Clayton via lldb-commits

https://github.com/clayborg closed 
https://github.com/llvm/llvm-project/pull/96243
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [llvm] Add support for using foreign type units in .debug_names. (PR #96243)

2024-06-20 Thread Greg Clayton via lldb-commits

clayborg wrote:

I got the original PR back on track...

https://github.com/llvm/llvm-project/pull/96243
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [llvm] Add support for using foreign type units in .debug_names. (PR #87740)

2024-06-20 Thread Greg Clayton via lldb-commits

clayborg wrote:

@ayermolo: you suggestion worked. thanks. This PR is back on track...

@labath: I implemented your suggestions, let me know if this look ok now

https://github.com/llvm/llvm-project/pull/87740
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [llvm] Add support for using foreign type units in .debug_names. (PR #87740)

2024-06-20 Thread Greg Clayton via lldb-commits

https://github.com/clayborg updated 
https://github.com/llvm/llvm-project/pull/87740

>From badd915257bb192add91696e0b8530c057bd385f Mon Sep 17 00:00:00 2001
From: Greg Clayton 
Date: Sat, 30 Mar 2024 10:50:34 -0700
Subject: [PATCH 01/11] Add support for using foreign type units in
 .debug_names.

This patch adds support for the new foreign type unit support in .debug_names. 
Features include:
- don't manually index foreign TUs if we have info for them
- only use the type unit entries that match the .dwo files when we have a .dwp 
file
- fix crashers that happen due to PeekDIEName() using wrong offsets
---
 .../SymbolFile/DWARF/DWARFDebugInfo.cpp   | 18 
 .../Plugins/SymbolFile/DWARF/DWARFDebugInfo.h |  2 +
 .../SymbolFile/DWARF/DebugNamesDWARFIndex.cpp | 65 -
 .../SymbolFile/DWARF/DebugNamesDWARFIndex.h   |  6 +-
 .../SymbolFile/DWARF/ManualDWARFIndex.cpp |  6 +-
 .../SymbolFile/DWARF/ManualDWARFIndex.h   |  7 +-
 .../SymbolFile/DWARF/SymbolFileDWARF.cpp  | 66 --
 .../SymbolFile/DWARF/SymbolFileDWARF.h|  9 ++
 .../DWARF/x86/dwp-foreign-type-units.cpp  | 91 +++
 .../DebugInfo/DWARF/DWARFAcceleratorTable.h   | 11 +++
 .../DebugInfo/DWARF/DWARFAcceleratorTable.cpp | 13 +++
 11 files changed, 257 insertions(+), 37 deletions(-)
 create mode 100644 
lldb/test/Shell/SymbolFile/DWARF/x86/dwp-foreign-type-units.cpp

diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp 
b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp
index c37cc91e08ed1..056c6d4b0605f 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp
@@ -222,6 +222,20 @@ DWARFUnit *DWARFDebugInfo::GetUnitAtOffset(DIERef::Section 
section,
   return result;
 }
 
+DWARFUnit *DWARFDebugInfo::GetUnit(const DIERef _ref) {
+  // Make sure we get the correct SymbolFileDWARF from the DIERef before
+  // asking for information from a debug info object. We might start with the
+  // DWARFDebugInfo for the main executable in a split DWARF and the DIERef
+  // might be pointing to a specific .dwo file or to the .dwp file. So this
+  // makes sure we get the right SymbolFileDWARF instance before finding the
+  // DWARFUnit that contains the offset. If we just use this object to do the
+  // search, we might be using the wrong .debug_info section from the wrong
+  // file with an offset meant for a different section.
+  SymbolFileDWARF *dwarf = m_dwarf.GetDIERefSymbolFile(die_ref);
+  return dwarf->DebugInfo().GetUnitContainingDIEOffset(die_ref.section(),
+   die_ref.die_offset());
+}
+
 DWARFUnit *
 DWARFDebugInfo::GetUnitContainingDIEOffset(DIERef::Section section,
dw_offset_t die_offset) {
@@ -232,6 +246,10 @@ DWARFDebugInfo::GetUnitContainingDIEOffset(DIERef::Section 
section,
   return result;
 }
 
+const std::shared_ptr DWARFDebugInfo::GetDwpSymbolFile() {
+  return m_dwarf.GetDwpSymbolFile();
+}
+
 DWARFTypeUnit *DWARFDebugInfo::GetTypeUnitForHash(uint64_t hash) {
   auto pos = llvm::lower_bound(m_type_hash_to_unit_index,
std::make_pair(hash, 0u), llvm::less_first());
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.h 
b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.h
index 4706b55d38ea9..4d4555a338252 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.h
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.h
@@ -52,6 +52,8 @@ class DWARFDebugInfo {
 
   const DWARFDebugAranges ();
 
+  const std::shared_ptr GetDwpSymbolFile();
+
 protected:
   typedef std::vector UnitColl;
 
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp 
b/lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp
index 1d17f20670eed..d815d345b08ee 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp
@@ -34,6 +34,18 @@ DebugNamesDWARFIndex::Create(Module , 
DWARFDataExtractor debug_names,
   module, std::move(index_up), debug_names, debug_str, dwarf));
 }
 
+
+llvm::DenseSet
+DebugNamesDWARFIndex::GetTypeUnitSigs(const DebugNames _names) {
+  llvm::DenseSet result;
+  for (const DebugNames::NameIndex  : debug_names) {
+const uint32_t num_tus = ni.getForeignTUCount();
+for (uint32_t tu = 0; tu < num_tus; ++tu)
+  result.insert(ni.getForeignTUSignature(tu));
+  }
+  return result;
+}
+
 llvm::DenseSet
 DebugNamesDWARFIndex::GetUnits(const DebugNames _names) {
   llvm::DenseSet result;
@@ -48,17 +60,22 @@ DebugNamesDWARFIndex::GetUnits(const DebugNames 
_names) {
   return result;
 }
 
+DWARFTypeUnit *
+DebugNamesDWARFIndex::GetForeignTypeUnit(const DebugNames::Entry ) const 
{
+  std::optional type_sig = entry.getForeignTUTypeSignature();
+  if (type_sig)
+if (auto dwp_sp = m_debug_info.GetDwpSymbolFile())
+  return 

[Lldb-commits] [lldb] [llvm] Add support for using foreign type units in .debug_names. (PR #96243)

2024-06-20 Thread Greg Clayton via lldb-commits

https://github.com/clayborg created 
https://github.com/llvm/llvm-project/pull/96243

This patch adds support for the new foreign type unit support in .debug_names. 
Features include:
- don't manually index foreign TUs if we have info for them
- only use the type unit entries that match the .dwo files when we have a .dwp 
file
- fix crashers that happen due to PeekDIEName() using wrong offsets
- support finding type unit entries in .dwp and .dwo files

This PR is a redo of https://github.com/llvm/llvm-project/pull/87740 after that 
branch had merging issues

>From c800f88b19d6e470e73c350ea5bcc88ce299f0eb Mon Sep 17 00:00:00 2001
From: Greg Clayton 
Date: Sat, 30 Mar 2024 10:50:34 -0700
Subject: [PATCH 01/10] Add support for using foreign type units in
 .debug_names.

This patch adds support for the new foreign type unit support in .debug_names. 
Features include:
- don't manually index foreign TUs if we have info for them
- only use the type unit entries that match the .dwo files when we have a .dwp 
file
- fix crashers that happen due to PeekDIEName() using wrong offsets
---
 .../SymbolFile/DWARF/DWARFDebugInfo.cpp   | 18 
 .../Plugins/SymbolFile/DWARF/DWARFDebugInfo.h |  2 +
 .../SymbolFile/DWARF/DebugNamesDWARFIndex.cpp | 65 -
 .../SymbolFile/DWARF/DebugNamesDWARFIndex.h   |  6 +-
 .../SymbolFile/DWARF/ManualDWARFIndex.cpp |  6 +-
 .../SymbolFile/DWARF/ManualDWARFIndex.h   |  7 +-
 .../SymbolFile/DWARF/SymbolFileDWARF.cpp  | 66 --
 .../SymbolFile/DWARF/SymbolFileDWARF.h|  9 ++
 .../DWARF/x86/dwp-foreign-type-units.cpp  | 91 +++
 .../DebugInfo/DWARF/DWARFAcceleratorTable.h   | 11 +++
 .../DebugInfo/DWARF/DWARFAcceleratorTable.cpp | 13 +++
 11 files changed, 257 insertions(+), 37 deletions(-)
 create mode 100644 
lldb/test/Shell/SymbolFile/DWARF/x86/dwp-foreign-type-units.cpp

diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp 
b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp
index c37cc91e08ed1..056c6d4b0605f 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp
@@ -222,6 +222,20 @@ DWARFUnit *DWARFDebugInfo::GetUnitAtOffset(DIERef::Section 
section,
   return result;
 }
 
+DWARFUnit *DWARFDebugInfo::GetUnit(const DIERef _ref) {
+  // Make sure we get the correct SymbolFileDWARF from the DIERef before
+  // asking for information from a debug info object. We might start with the
+  // DWARFDebugInfo for the main executable in a split DWARF and the DIERef
+  // might be pointing to a specific .dwo file or to the .dwp file. So this
+  // makes sure we get the right SymbolFileDWARF instance before finding the
+  // DWARFUnit that contains the offset. If we just use this object to do the
+  // search, we might be using the wrong .debug_info section from the wrong
+  // file with an offset meant for a different section.
+  SymbolFileDWARF *dwarf = m_dwarf.GetDIERefSymbolFile(die_ref);
+  return dwarf->DebugInfo().GetUnitContainingDIEOffset(die_ref.section(),
+   die_ref.die_offset());
+}
+
 DWARFUnit *
 DWARFDebugInfo::GetUnitContainingDIEOffset(DIERef::Section section,
dw_offset_t die_offset) {
@@ -232,6 +246,10 @@ DWARFDebugInfo::GetUnitContainingDIEOffset(DIERef::Section 
section,
   return result;
 }
 
+const std::shared_ptr DWARFDebugInfo::GetDwpSymbolFile() {
+  return m_dwarf.GetDwpSymbolFile();
+}
+
 DWARFTypeUnit *DWARFDebugInfo::GetTypeUnitForHash(uint64_t hash) {
   auto pos = llvm::lower_bound(m_type_hash_to_unit_index,
std::make_pair(hash, 0u), llvm::less_first());
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.h 
b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.h
index 4706b55d38ea9..4d4555a338252 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.h
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.h
@@ -52,6 +52,8 @@ class DWARFDebugInfo {
 
   const DWARFDebugAranges ();
 
+  const std::shared_ptr GetDwpSymbolFile();
+
 protected:
   typedef std::vector UnitColl;
 
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp 
b/lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp
index 1d17f20670eed..d815d345b08ee 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp
@@ -34,6 +34,18 @@ DebugNamesDWARFIndex::Create(Module , 
DWARFDataExtractor debug_names,
   module, std::move(index_up), debug_names, debug_str, dwarf));
 }
 
+
+llvm::DenseSet
+DebugNamesDWARFIndex::GetTypeUnitSigs(const DebugNames _names) {
+  llvm::DenseSet result;
+  for (const DebugNames::NameIndex  : debug_names) {
+const uint32_t num_tus = ni.getForeignTUCount();
+for (uint32_t tu = 0; tu < num_tus; ++tu)
+  result.insert(ni.getForeignTUSignature(tu));

[Lldb-commits] [lldb] [lldb][API] Add Find(Ranges)InMemory() to Process SB API (PR #95007)

2024-06-20 Thread Greg Clayton via lldb-commits


@@ -101,3 +101,5 @@ bool SBAddressRange::GetDescription(SBStream ,
   m_opaque_up->GetDescription(, target.GetSP().get());
   return true;
 }
+
+lldb_private::AddressRange ::ref() const { return *m_opaque_up; 
}

clayborg wrote:

This is no longer needed right? This PR contains this fix right? 
https://github.com/llvm/llvm-project/pull/95997

https://github.com/llvm/llvm-project/pull/95007
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb][API] Add Find(Ranges)InMemory() to Process SB API (PR #95007)

2024-06-20 Thread Greg Clayton via lldb-commits


@@ -2800,6 +2809,10 @@ void PruneThreadPlans();
   virtual size_t DoReadMemory(lldb::addr_t vm_addr, void *buf, size_t size,
   Status ) = 0;
 
+  void DoFindInMemory(lldb::addr_t start_addr, lldb::addr_t end_addr,
+  const uint8_t *buf, size_t size, AddressRanges ,
+  size_t alignment, size_t max_matches);
+

clayborg wrote:

We might want this to be virtual to allow core files to do this quicker than 
having to read all memory into a buffer. 

https://github.com/llvm/llvm-project/pull/95007
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb][API] Add Find(Ranges)InMemory() to Process SB API (PR #95007)

2024-06-20 Thread Greg Clayton via lldb-commits


@@ -92,3 +92,7 @@ bool SBAddressRangeList::GetDescription(SBStream ,
   stream << "]";
   return true;
 }
+
+lldb_private::AddressRanges ::ref() const {
+  return m_opaque_up->ref();
+}

clayborg wrote:

we might want to add an `assert()` call here like you did for 
`SBAddressRange::ref()`?

https://github.com/llvm/llvm-project/pull/95007
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb][API] Add Find(Ranges)InMemory() to Process SB API (PR #95007)

2024-06-20 Thread Greg Clayton via lldb-commits


@@ -64,7 +64,7 @@ bool SBAddressRange::operator!=(const SBAddressRange ) {
 void SBAddressRange::Clear() {
   LLDB_INSTRUMENT_VA(this);
 
-  m_opaque_up.reset();
+  m_opaque_up->Clear();

clayborg wrote:

This is no longer needed right? This PR contains this fix right? 
https://github.com/llvm/llvm-project/pull/95997

https://github.com/llvm/llvm-project/pull/95007
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb][API] Add Find(Ranges)InMemory() to Process SB API (PR #95007)

2024-06-20 Thread Greg Clayton via lldb-commits


@@ -2007,6 +2007,135 @@ size_t Process::ReadMemory(addr_t addr, void *buf, 
size_t size, Status ) {
   }
 }
 
+void Process::DoFindInMemory(lldb::addr_t start_addr, lldb::addr_t end_addr,
+ const uint8_t *buf, size_t size,
+ AddressRanges , size_t alignment,
+ size_t max_matches) {
+  // Inputs are already validated in FindInMemory() functions.
+  assert(buf != nullptr);
+  assert(size > 0);
+  assert(alignment > 0);
+  assert(max_matches > 0);
+  assert(start_addr != LLDB_INVALID_ADDRESS);
+  assert(end_addr != LLDB_INVALID_ADDRESS);
+  assert(start_addr < end_addr);
+
+  lldb::addr_t start = start_addr;
+  if (alignment > 1) {
+// Align to an address alignment boundary
+const uint64_t align_offset = start % alignment;
+if (align_offset > 0)
+  start += alignment - align_offset;
+  }
+  while (matches.size() < max_matches && (start + size) < end_addr) {
+const lldb::addr_t found_addr = FindInMemory(start, end_addr, buf, size);
+if (found_addr == LLDB_INVALID_ADDRESS)
+  break;
+
+if (found_addr % alignment) {
+  ++start;
+  continue;
+}
+
+matches.emplace_back(found_addr, size);
+start = found_addr + alignment;
+  }
+}
+
+AddressRanges Process::FindRangesInMemory(const uint8_t *buf, uint64_t size,
+  const AddressRanges ,
+  size_t alignment, size_t max_matches,
+  Status ) {
+  AddressRanges matches;
+  if (buf == nullptr) {
+error.SetErrorString("buffer is null");
+return matches;
+  }
+  if (size == 0) {
+error.SetErrorString("buffer size is zero");
+return matches;
+  }
+  if (ranges.empty()) {
+error.SetErrorString("empty ranges");
+return matches;
+  }
+  if (alignment == 0) {
+error.SetErrorString("alignment must be greater than zero");
+return matches;
+  }
+  if (max_matches == 0) {
+error.SetErrorStringWithFormat("max_matches must be greater than zero");

clayborg wrote:

use `error.SetErrorString()` if there are no formats being applied

https://github.com/llvm/llvm-project/pull/95007
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb][API] Add Find(Ranges)InMemory() to Process SB API (PR #95007)

2024-06-20 Thread Greg Clayton via lldb-commits


@@ -58,6 +58,8 @@ class LLDB_API SBAddressRange {
   friend class SBFunction;
   friend class SBProcess;
 
+  lldb_private::AddressRange () const;
+

clayborg wrote:

This is no longer needed right? This PR contains this fix right? 
https://github.com/llvm/llvm-project/pull/95997

https://github.com/llvm/llvm-project/pull/95007
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] Fix SBAddressRange validation checks. (PR #95997)

2024-06-20 Thread Greg Clayton via lldb-commits

https://github.com/clayborg approved this pull request.


https://github.com/llvm/llvm-project/pull/95997
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] Fix SBAddressRange validation checks. (PR #95997)

2024-06-20 Thread Greg Clayton via lldb-commits

clayborg wrote:

> This class behaves quite differently from other SB API classes. Normally, the 
> opaque pointer can be cleared to release the potentially more resource heavy 
> private counterpart. `AddressRange` is a pretty simple class, so I understand 
> that it makes things easier if we guarantee the pointer is always valid, but 
> it is somewhat of a surprise.
> 
> Personally, I think consistency beats the small advantage of not having to 
> check the pointer. If we want to stick to this approach, I'd like to see an 
> assert that makes it clear that in this class, we have a precondition that 
> the pointer is always valid:
> 
> ```
> assert(m_opaque_up && "opaque pointer must always be valid");
> ```

For simple classes, there is no need to clear the unique pointer, so I like 
this approach for small classes.

We can use the assert in a new protected `ref()` method:
```
lldb_private::AddressRange & SBAddressRange::ref() {
  assert(m_opaque_up && "opaque pointer must always be valid");
  return *m_opaque_up;
}
```
And then have everything that accesses `m_opaque_up` use the `ref()` function. 
It is similar to other classes and makes the code nicer when we don't see 
direct uses of `m_opaque_up`

https://github.com/llvm/llvm-project/pull/95997
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] Add/change options in `statistics dump` to control what sections are dumped (PR #95075)

2024-06-18 Thread Greg Clayton via lldb-commits

https://github.com/clayborg closed 
https://github.com/llvm/llvm-project/pull/95075
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] Fix SBAddressRange validation checks. (PR #95997)

2024-06-18 Thread Greg Clayton via lldb-commits

https://github.com/clayborg approved this pull request.


https://github.com/llvm/llvm-project/pull/95997
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] Add/change options in `statistics dump` to control what sections are dumped (PR #95075)

2024-06-18 Thread Greg Clayton via lldb-commits

https://github.com/clayborg approved this pull request.


https://github.com/llvm/llvm-project/pull/95075
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [llvm] [LLDB][Minidump] Add 64b support to LLDB's minidump file builder. (PR #95312)

2024-06-18 Thread Greg Clayton via lldb-commits

https://github.com/clayborg approved this pull request.

Looks good to me!

https://github.com/llvm/llvm-project/pull/95312
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [llvm] [LLDB][Minidump] Add 64b support to LLDB's minidump file builder. (PR #95312)

2024-06-17 Thread Greg Clayton via lldb-commits


@@ -791,26 +807,101 @@ void MinidumpFileBuilder::AddLinuxFileStreams(
   size_t size = memory_buffer->getBufferSize();
   if (size == 0)
 continue;
-  AddDirectory(stream, size);
+  error = AddDirectory(stream, size);
+  if (error.Fail())
+return error;
   m_data.AppendData(memory_buffer->getBufferStart(), size);
 }
   }
+
+  return error;
 }
 
-Status MinidumpFileBuilder::Dump(lldb::FileUP _file) const {
-  constexpr size_t header_size = sizeof(llvm::minidump::Header);
-  constexpr size_t directory_size = sizeof(llvm::minidump::Directory);
+Status MinidumpFileBuilder::AddMemoryList(SaveCoreStyle core_style) {
+  Status error;
+
+  // We first save the thread stacks to ensure they fit in the first UINT32_MAX
+  // bytes of the core file. Thread structures in minidump files can only use
+  // 32 bit memory descriptiors, so we emit them first to ensure the memory is
+  // in accessible with a 32 bit offset.
+  Process::CoreFileMemoryRanges ranges_32;
+  Process::CoreFileMemoryRanges ranges_64;
+  error = m_process_sp->CalculateCoreFileSaveRanges(
+  SaveCoreStyle::eSaveCoreStackOnly, ranges_32);
+  if (error.Fail())
+return error;
 
+  uint64_t total_size =
+  ranges_32.size() * sizeof(llvm::minidump::MemoryDescriptor);
+  std::unordered_set stack_start_addresses;
+  for (const auto _range : ranges_32) {
+stack_start_addresses.insert(core_range.range.start());
+total_size += core_range.range.size();
+  }
+
+  if (total_size >= UINT32_MAX) {
+error.SetErrorStringWithFormat("Unable to write minidump. Stack memory "
+   "exceeds 32b limit. (Num Stacks %zu)",
+   ranges_32.size());
+return error;
+  }
+
+  Process::CoreFileMemoryRanges all_core_memory_ranges;
+  if (core_style != SaveCoreStyle::eSaveCoreStackOnly) {
+error = m_process_sp->CalculateCoreFileSaveRanges(core_style,
+  all_core_memory_ranges);
+if (error.Fail())
+  return error;
+  }
+
+  // After saving the stacks, we start packing as much as we can into 32b.
+  // We apply a generous padding here so that the Directory, MemoryList and
+  // Memory64List sections all begin in 32b addressable space.
+  // Then anything overflow extends into 64b addressable space.
+  total_size +=
+  256 + (all_core_memory_ranges.size() - stack_start_addresses.size()) *
+sizeof(llvm::minidump::MemoryDescriptor_64);
+
+  for (const auto _range : all_core_memory_ranges) {
+addr_t range_size = core_range.range.size();

clayborg wrote:

make `const`

https://github.com/llvm/llvm-project/pull/95312
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [llvm] [LLDB][Minidump] Add 64b support to LLDB's minidump file builder. (PR #95312)

2024-06-17 Thread Greg Clayton via lldb-commits


@@ -791,26 +807,101 @@ void MinidumpFileBuilder::AddLinuxFileStreams(
   size_t size = memory_buffer->getBufferSize();
   if (size == 0)
 continue;
-  AddDirectory(stream, size);
+  error = AddDirectory(stream, size);
+  if (error.Fail())
+return error;
   m_data.AppendData(memory_buffer->getBufferStart(), size);
 }
   }
+
+  return error;
 }
 
-Status MinidumpFileBuilder::Dump(lldb::FileUP _file) const {
-  constexpr size_t header_size = sizeof(llvm::minidump::Header);
-  constexpr size_t directory_size = sizeof(llvm::minidump::Directory);
+Status MinidumpFileBuilder::AddMemoryList(SaveCoreStyle core_style) {
+  Status error;
+
+  // We first save the thread stacks to ensure they fit in the first UINT32_MAX
+  // bytes of the core file. Thread structures in minidump files can only use
+  // 32 bit memory descriptiors, so we emit them first to ensure the memory is
+  // in accessible with a 32 bit offset.
+  Process::CoreFileMemoryRanges ranges_32;
+  Process::CoreFileMemoryRanges ranges_64;
+  error = m_process_sp->CalculateCoreFileSaveRanges(
+  SaveCoreStyle::eSaveCoreStackOnly, ranges_32);
+  if (error.Fail())
+return error;
 
+  uint64_t total_size =
+  ranges_32.size() * sizeof(llvm::minidump::MemoryDescriptor);
+  std::unordered_set stack_start_addresses;
+  for (const auto _range : ranges_32) {
+stack_start_addresses.insert(core_range.range.start());
+total_size += core_range.range.size();
+  }
+
+  if (total_size >= UINT32_MAX) {
+error.SetErrorStringWithFormat("Unable to write minidump. Stack memory "
+   "exceeds 32b limit. (Num Stacks %zu)",
+   ranges_32.size());
+return error;
+  }
+
+  Process::CoreFileMemoryRanges all_core_memory_ranges;
+  if (core_style != SaveCoreStyle::eSaveCoreStackOnly) {
+error = m_process_sp->CalculateCoreFileSaveRanges(core_style,
+  all_core_memory_ranges);
+if (error.Fail())
+  return error;
+  }
+
+  // After saving the stacks, we start packing as much as we can into 32b.
+  // We apply a generous padding here so that the Directory, MemoryList and
+  // Memory64List sections all begin in 32b addressable space.
+  // Then anything overflow extends into 64b addressable space.
+  total_size +=
+  256 + (all_core_memory_ranges.size() - stack_start_addresses.size()) *
+sizeof(llvm::minidump::MemoryDescriptor_64);

clayborg wrote:

this `total_size` will be wrong if `all_core_memory_ranges` is empty right? If 
we are saving stacks only, this will be:
```
256 + (0 - stack_start_addresses.size()) * 
sizeof(llvm::minidump::MemoryDescriptor_64);
```
And we will unsigned underflow but it won't matter because we won't use 
`total_size`. Best to put a:
```
if (!all_core_memory_ranges.empty()) {
```
around the `total_size` and for loop that iterates over all core ranges to 
avoid potential issues in the future.

https://github.com/llvm/llvm-project/pull/95312
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [llvm] [LLDB][Minidump] Add 64b support to LLDB's minidump file builder. (PR #95312)

2024-06-17 Thread Greg Clayton via lldb-commits


@@ -20,25 +20,98 @@
 #include "lldb/Target/RegisterContext.h"
 #include "lldb/Target/StopInfo.h"
 #include "lldb/Target/ThreadList.h"
+#include "lldb/Utility/DataBufferHeap.h"
 #include "lldb/Utility/DataExtractor.h"
 #include "lldb/Utility/LLDBLog.h"
 #include "lldb/Utility/Log.h"
+#include "lldb/Utility/RangeMap.h"
 #include "lldb/Utility/RegisterValue.h"
 
 #include "llvm/ADT/StringRef.h"
 #include "llvm/BinaryFormat/Minidump.h"
 #include "llvm/Support/ConvertUTF.h"
+#include "llvm/Support/Endian.h"
 #include "llvm/Support/Error.h"
+#include "llvm/TargetParser/Triple.h"
 
 #include "Plugins/Process/minidump/MinidumpTypes.h"
+#include "lldb/lldb-enumerations.h"
+#include "lldb/lldb-forward.h"
+#include "lldb/lldb-types.h"
 
+#include 
 #include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
 
 using namespace lldb;
 using namespace lldb_private;
 using namespace llvm::minidump;
 
-void MinidumpFileBuilder::AddDirectory(StreamType type, size_t stream_size) {
+Status MinidumpFileBuilder::AddHeaderAndCalculateDirectories() {
+  // First set the offset on the file, and on the bytes saved
+  m_saved_data_size = HEADER_SIZE;
+  // We know we will have at least Misc, SystemInfo, Modules, and ThreadList
+  // (corresponding memory list for stacks) And an additional memory list for
+  // non-stacks.
+  lldb_private::Target  = m_process_sp->GetTarget();
+  m_expected_directories = 6;
+  // Check if OS is linux and reserve directory space for all linux specific
+  // breakpad extension directories.
+  if (target.GetArchitecture().GetTriple().getOS() ==
+  llvm::Triple::OSType::Linux)
+m_expected_directories += 9;
+
+  // Go through all of the threads and check for exceptions.
+  lldb_private::ThreadList thread_list = m_process_sp->GetThreadList();
+  const uint32_t num_threads = thread_list.GetSize();
+  for (uint32_t thread_idx = 0; thread_idx < num_threads; ++thread_idx) {
+ThreadSP thread_sp(thread_list.GetThreadAtIndex(thread_idx));
+StopInfoSP stop_info_sp = thread_sp->GetStopInfo();
+if (stop_info_sp &&
+stop_info_sp->GetStopReason() == StopReason::eStopReasonException) {
+  m_expected_directories++;
+}
+  }
+
+  m_saved_data_size +=
+  m_expected_directories * sizeof(llvm::minidump::Directory);
+  Status error;
+  offset_t new_offset = m_core_file->SeekFromStart(m_saved_data_size);
+  if (new_offset != m_saved_data_size)
+error.SetErrorStringWithFormat("Failed to fill in header and directory "
+   "sections. Written / Expected (%" PRIx64
+   " / %zu)",

clayborg wrote:

`m_saved_data_size` is uint64_t, so don't use `" / %zu)`, use ` / %" PRIu64 ")"

https://github.com/llvm/llvm-project/pull/95312
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [llvm] [LLDB][Minidump] Add 64b support to LLDB's minidump file builder. (PR #95312)

2024-06-17 Thread Greg Clayton via lldb-commits


@@ -791,26 +807,101 @@ void MinidumpFileBuilder::AddLinuxFileStreams(
   size_t size = memory_buffer->getBufferSize();
   if (size == 0)
 continue;
-  AddDirectory(stream, size);
+  error = AddDirectory(stream, size);
+  if (error.Fail())
+return error;
   m_data.AppendData(memory_buffer->getBufferStart(), size);
 }
   }
+
+  return error;
 }
 
-Status MinidumpFileBuilder::Dump(lldb::FileUP _file) const {
-  constexpr size_t header_size = sizeof(llvm::minidump::Header);
-  constexpr size_t directory_size = sizeof(llvm::minidump::Directory);
+Status MinidumpFileBuilder::AddMemoryList(SaveCoreStyle core_style) {
+  Status error;
+
+  // We first save the thread stacks to ensure they fit in the first UINT32_MAX
+  // bytes of the core file. Thread structures in minidump files can only use
+  // 32 bit memory descriptiors, so we emit them first to ensure the memory is
+  // in accessible with a 32 bit offset.
+  Process::CoreFileMemoryRanges ranges_32;
+  Process::CoreFileMemoryRanges ranges_64;
+  error = m_process_sp->CalculateCoreFileSaveRanges(
+  SaveCoreStyle::eSaveCoreStackOnly, ranges_32);
+  if (error.Fail())
+return error;
 
+  uint64_t total_size =
+  ranges_32.size() * sizeof(llvm::minidump::MemoryDescriptor);
+  std::unordered_set stack_start_addresses;
+  for (const auto _range : ranges_32) {
+stack_start_addresses.insert(core_range.range.start());
+total_size += core_range.range.size();
+  }
+
+  if (total_size >= UINT32_MAX) {
+error.SetErrorStringWithFormat("Unable to write minidump. Stack memory "
+   "exceeds 32b limit. (Num Stacks %zu)",
+   ranges_32.size());
+return error;
+  }
+
+  Process::CoreFileMemoryRanges all_core_memory_ranges;
+  if (core_style != SaveCoreStyle::eSaveCoreStackOnly) {
+error = m_process_sp->CalculateCoreFileSaveRanges(core_style,
+  all_core_memory_ranges);
+if (error.Fail())
+  return error;
+  }
+
+  // After saving the stacks, we start packing as much as we can into 32b.
+  // We apply a generous padding here so that the Directory, MemoryList and
+  // Memory64List sections all begin in 32b addressable space.
+  // Then anything overflow extends into 64b addressable space.
+  total_size +=
+  256 + (all_core_memory_ranges.size() - stack_start_addresses.size()) *
+sizeof(llvm::minidump::MemoryDescriptor_64);
+
+  for (const auto _range : all_core_memory_ranges) {
+addr_t range_size = core_range.range.size();
+if (stack_start_addresses.count(core_range.range.start()) > 0)
+  // Don't double save stacks.
+  continue;
+
+if (total_size + range_size < UINT32_MAX) {
+  ranges_32.push_back(core_range);
+  total_size += core_range.range.size();

clayborg wrote:

use `range_size` that you created above.

https://github.com/llvm/llvm-project/pull/95312
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] Add/change options in `statistics dump` to control what sections are dumped (PR #95075)

2024-06-17 Thread Greg Clayton via lldb-commits


@@ -29,6 +29,9 @@ struct OptionArgParser {
 
   static bool ToBoolean(llvm::StringRef s, bool fail_value, bool *success_ptr);
 
+  static bool ToBoolean(llvm::StringRef option_name, llvm::StringRef 
option_arg,
+bool fail_value, Status );
+

clayborg wrote:

If we are going to add a function here I would suggest we add it with 
`llvm::Expected`:
```
llvm::Expected ToBoolean(llvm::StringRef option_arg);
```
This will return a `bool` or a `llvm::Error`. `lldb_private::Status` has a 
constructor that takes an `llvm::Error`. I will show how to use this in the new 
code below.

https://github.com/llvm/llvm-project/pull/95075
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] Add/change options in `statistics dump` to control what sections are dumped (PR #95075)

2024-06-17 Thread Greg Clayton via lldb-commits


@@ -1425,8 +1425,21 @@ let Command = "statistics dump" in {
 Desc<"Dump the total possible debug info statistics. "
 "Force loading all the debug information if not yet loaded, and collect "
 "statistics with those.">;
+  def statistics_dump_targets: Option<"targets", "r">, Group<1>,
+Arg<"Boolean">,
+Desc<"Dump statistics for the targets, including breakpoints, expression "
+"evaluations, frame variables, etc. "
+"If both the '--targets' and the '--modules' options are 'true', a list "
+"of module identifiers will be added to the 'targets' section.">;

clayborg wrote:

Talk about the default value for this as mentioned below. 

https://github.com/llvm/llvm-project/pull/95075
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] Add/change options in `statistics dump` to control what sections are dumped (PR #95075)

2024-06-17 Thread Greg Clayton via lldb-commits


@@ -76,13 +77,22 @@ class CommandObjectStatsDump : public CommandObjectParsed {
 m_all_targets = true;
 break;
   case 's':
-m_stats_options.summary_only = true;
+m_stats_options.SetSummaryOnly(true);
 break;
   case 'f':
-m_stats_options.load_all_debug_info = true;
+m_stats_options.SetLoadAllDebugInfo(true);
+break;
+  case 'r':
+m_stats_options.SetIncludeTargets(OptionArgParser::ToBoolean(
+"--targets", option_arg, true /* doesn't matter */, error));
+break;
+  case 'm':
+m_stats_options.SetIncludeModules(OptionArgParser::ToBoolean(
+"--modules", option_arg, true /* doesn't matter */, error));
 break;
   case 't':
-m_stats_options.include_transcript = true;
+m_stats_options.SetIncludeTranscript(OptionArgParser::ToBoolean(
+"--transcript", option_arg, true /* doesn't matter */, error));

clayborg wrote:

Ditto.

https://github.com/llvm/llvm-project/pull/95075
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] Add/change options in `statistics dump` to control what sections are dumped (PR #95075)

2024-06-17 Thread Greg Clayton via lldb-commits


@@ -1425,8 +1425,21 @@ let Command = "statistics dump" in {
 Desc<"Dump the total possible debug info statistics. "
 "Force loading all the debug information if not yet loaded, and collect "
 "statistics with those.">;
+  def statistics_dump_targets: Option<"targets", "r">, Group<1>,
+Arg<"Boolean">,
+Desc<"Dump statistics for the targets, including breakpoints, expression "
+"evaluations, frame variables, etc. "
+"If both the '--targets' and the '--modules' options are 'true', a list "
+"of module identifiers will be added to the 'targets' section.">;
+  def statistics_dump_modules: Option<"modules", "m">, Group<1>,
+Arg<"Boolean">,
+Desc<"Dump statistics for the modules, including time and size of various "
+"aspects of the module and debug information, type system, path, etc. "
+"If both the '--targets' and the '--modules' options are 'true', a list "
+"of module identifiers will be added to the 'targets' section.">;

clayborg wrote:

Talk about the default value for this and what will turn this on or off. This 
defaults to `true` unless the `--summary` mode is enabled which will turn it 
off unless this is specified.

https://github.com/llvm/llvm-project/pull/95075
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] Add/change options in `statistics dump` to control what sections are dumped (PR #95075)

2024-06-17 Thread Greg Clayton via lldb-commits


@@ -76,13 +77,22 @@ class CommandObjectStatsDump : public CommandObjectParsed {
 m_all_targets = true;
 break;
   case 's':
-m_stats_options.summary_only = true;
+m_stats_options.SetSummaryOnly(true);
 break;
   case 'f':
-m_stats_options.load_all_debug_info = true;
+m_stats_options.SetLoadAllDebugInfo(true);
+break;
+  case 'r':
+m_stats_options.SetIncludeTargets(OptionArgParser::ToBoolean(
+"--targets", option_arg, true /* doesn't matter */, error));
+break;
+  case 'm':
+m_stats_options.SetIncludeModules(OptionArgParser::ToBoolean(
+"--modules", option_arg, true /* doesn't matter */, error));

clayborg wrote:

Ditto, use `llvm::Expected ToBoolean(llvm::StringRef option_arg);` as 
above

https://github.com/llvm/llvm-project/pull/95075
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] Add/change options in `statistics dump` to control what sections are dumped (PR #95075)

2024-06-17 Thread Greg Clayton via lldb-commits


@@ -76,13 +77,22 @@ class CommandObjectStatsDump : public CommandObjectParsed {
 m_all_targets = true;
 break;
   case 's':
-m_stats_options.summary_only = true;
+m_stats_options.SetSummaryOnly(true);
 break;
   case 'f':
-m_stats_options.load_all_debug_info = true;
+m_stats_options.SetLoadAllDebugInfo(true);
+break;
+  case 'r':
+m_stats_options.SetIncludeTargets(OptionArgParser::ToBoolean(
+"--targets", option_arg, true /* doesn't matter */, error));

clayborg wrote:

Lets use the new `llvm::Expected ToBoolean(llvm::StringRef option_arg);` 
function:
```
if (auto bool_or_error = OptionArgParser::ToBoolean(option_arg))
  m_stats_options.SetIncludeTargets(*bool_or_error);
else
  error.SetErrorStringWithFormat("failed to parse --targets boolean value: %s", 
llvm::toString(bool_or_error.takeError()).c_str());
```
  

https://github.com/llvm/llvm-project/pull/95075
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [lldb] Add/change options in `statistics dump` to control what sections are dumped (PR #95075)

2024-06-17 Thread Greg Clayton via lldb-commits


@@ -25,6 +25,15 @@ class LLDB_API SBStatisticsOptions {
   void SetSummaryOnly(bool b);
   bool GetSummaryOnly();
 
+  void SetIncludeTargets(bool b);
+  bool GetIncludeTargets() const;
+
+  void SetIncludeModules(bool b);
+  bool GetIncludeModules() const;
+
+  void SetIncludeTranscript(bool b);
+  bool GetIncludeTranscript() const;
+

clayborg wrote:

Lets add some header doc here that explains what the default values are for 
each scenario so people know what these will do.

https://github.com/llvm/llvm-project/pull/95075
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [llvm] [LLDB][Minidump] Add 64b support to LLDB's minidump file builder. (PR #95312)

2024-06-17 Thread Greg Clayton via lldb-commits


@@ -821,47 +908,285 @@ Status MinidumpFileBuilder::Dump(lldb::FileUP 
_file) const {
   Status error;
   size_t bytes_written;
 
-  bytes_written = header_size;
-  error = core_file->Write(, bytes_written);
-  if (error.Fail() || bytes_written != header_size) {
-if (bytes_written != header_size)
+  m_core_file->SeekFromStart(0);
+  bytes_written = HEADER_SIZE;
+  error = m_core_file->Write(, bytes_written);
+  if (error.Fail() || bytes_written != HEADER_SIZE) {
+if (bytes_written != HEADER_SIZE)
   error.SetErrorStringWithFormat(
-  "unable to write the header (written %zd/%zd)", bytes_written,
-  header_size);
+  "Unable to write the minidump header (written %zd/%zd)",
+  bytes_written, HEADER_SIZE);
 return error;
   }
+  return error;
+}
 
-  // write data
-  bytes_written = m_data.GetByteSize();
-  error = core_file->Write(m_data.GetBytes(), bytes_written);
-  if (error.Fail() || bytes_written != m_data.GetByteSize()) {
-if (bytes_written != m_data.GetByteSize())
-  error.SetErrorStringWithFormat(
-  "unable to write the data (written %zd/%" PRIu64 ")", bytes_written,
-  m_data.GetByteSize());
-return error;
-  }
+size_t MinidumpFileBuilder::GetCurrentDataEndOffset() const {
+  return m_data.GetByteSize() + m_saved_data_size;
+}
 
-  // write directories
+Status MinidumpFileBuilder::DumpDirectories() const {
+  Status error;
+  size_t bytes_written;
+  m_core_file->SeekFromStart(HEADER_SIZE);
   for (const Directory  : m_directories) {
-bytes_written = directory_size;
-error = core_file->Write(, bytes_written);
-if (error.Fail() || bytes_written != directory_size) {
-  if (bytes_written != directory_size)
+bytes_written = DIRECTORY_SIZE;
+error = m_core_file->Write(, bytes_written);
+if (error.Fail() || bytes_written != DIRECTORY_SIZE) {
+  if (bytes_written != DIRECTORY_SIZE)
 error.SetErrorStringWithFormat(
 "unable to write the directory (written %zd/%zd)", bytes_written,
-directory_size);
+DIRECTORY_SIZE);
   return error;
 }
   }
 
   return error;
 }
 
-size_t MinidumpFileBuilder::GetDirectoriesNum() const {
-  return m_directories.size();
+static size_t GetLargestRange(const Process::CoreFileMemoryRanges ) {
+  size_t max_size = 0;
+  for (const auto _range : ranges)
+max_size = std::max(max_size, core_range.range.size());
+  return max_size;
 }
 
-size_t MinidumpFileBuilder::GetCurrentDataEndOffset() const {
-  return sizeof(llvm::minidump::Header) + m_data.GetByteSize();
+Status
+MinidumpFileBuilder::AddMemoryList_32(Process::CoreFileMemoryRanges ) {
+  std::vector descriptors;
+  Status error;
+  if (ranges.size() == 0)
+return error;
+
+  Log *log = GetLog(LLDBLog::Object);
+  size_t region_index = 0;
+  auto data_up = std::make_unique(GetLargestRange(ranges), 0);
+  for (const auto _range : ranges) {
+// Take the offset before we write.
+const size_t offset_for_data = GetCurrentDataEndOffset();
+const addr_t addr = core_range.range.start();
+const addr_t size = core_range.range.size();
+const addr_t end = core_range.range.end();
+
+LLDB_LOGF(log,
+  "AddMemoryList %zu/%zu reading memory for region "
+  "(%zu bytes) [%zx, %zx)",
+  region_index, ranges.size(), size, addr, addr + size);
+++region_index;
+
+const size_t bytes_read =
+m_process_sp->ReadMemory(addr, data_up->GetBytes(), size, error);
+if (error.Fail() || bytes_read == 0) {
+  LLDB_LOGF(log, "Failed to read memory region. Bytes read: %zu, error: 
%s",
+bytes_read, error.AsCString());
+  // Just skip sections with errors or zero bytes in 32b mode
+  continue;
+} else if (bytes_read != size) {
+  LLDB_LOGF(log, "Memory region at: %zu failed to read %zu bytes", addr,
+size);
+}
+
+MemoryDescriptor descriptor;
+descriptor.StartOfMemoryRange =
+static_cast(addr);
+descriptor.Memory.DataSize =
+static_cast(bytes_read);
+descriptor.Memory.RVA =
+static_cast(offset_for_data);
+descriptors.push_back(descriptor);
+if (m_thread_by_range_end.count(end) > 0)
+  m_thread_by_range_end[end].Stack = descriptor;
+
+// Add the data to the buffer, flush as needed.
+error = AddData(data_up->GetBytes(), bytes_read);
+if (error.Fail())
+  return error;
+  }
+
+  // Add a directory that references this list
+  // With a size of the number of ranges as a 32 bit num
+  // And then the size of all the ranges
+  error = AddDirectory(StreamType::MemoryList,
+   sizeof(llvm::support::ulittle32_t) +
+   descriptors.size() *
+   sizeof(llvm::minidump::MemoryDescriptor));
+  if (error.Fail())
+return error;
+
+  llvm::support::ulittle32_t memory_ranges_num =
+  static_cast(descriptors.size());
+  

[Lldb-commits] [lldb] [llvm] [LLDB][Minidump] Add 64b support to LLDB's minidump file builder. (PR #95312)

2024-06-17 Thread Greg Clayton via lldb-commits


@@ -821,47 +908,285 @@ Status MinidumpFileBuilder::Dump(lldb::FileUP 
_file) const {
   Status error;
   size_t bytes_written;
 
-  bytes_written = header_size;
-  error = core_file->Write(, bytes_written);
-  if (error.Fail() || bytes_written != header_size) {
-if (bytes_written != header_size)
+  m_core_file->SeekFromStart(0);
+  bytes_written = HEADER_SIZE;
+  error = m_core_file->Write(, bytes_written);
+  if (error.Fail() || bytes_written != HEADER_SIZE) {
+if (bytes_written != HEADER_SIZE)
   error.SetErrorStringWithFormat(
-  "unable to write the header (written %zd/%zd)", bytes_written,
-  header_size);
+  "Unable to write the minidump header (written %zd/%zd)",
+  bytes_written, HEADER_SIZE);
 return error;
   }
+  return error;
+}
 
-  // write data
-  bytes_written = m_data.GetByteSize();
-  error = core_file->Write(m_data.GetBytes(), bytes_written);
-  if (error.Fail() || bytes_written != m_data.GetByteSize()) {
-if (bytes_written != m_data.GetByteSize())
-  error.SetErrorStringWithFormat(
-  "unable to write the data (written %zd/%" PRIu64 ")", bytes_written,
-  m_data.GetByteSize());
-return error;
-  }
+size_t MinidumpFileBuilder::GetCurrentDataEndOffset() const {
+  return m_data.GetByteSize() + m_saved_data_size;
+}
 
-  // write directories
+Status MinidumpFileBuilder::DumpDirectories() const {
+  Status error;
+  size_t bytes_written;
+  m_core_file->SeekFromStart(HEADER_SIZE);
   for (const Directory  : m_directories) {
-bytes_written = directory_size;
-error = core_file->Write(, bytes_written);
-if (error.Fail() || bytes_written != directory_size) {
-  if (bytes_written != directory_size)
+bytes_written = DIRECTORY_SIZE;
+error = m_core_file->Write(, bytes_written);
+if (error.Fail() || bytes_written != DIRECTORY_SIZE) {
+  if (bytes_written != DIRECTORY_SIZE)
 error.SetErrorStringWithFormat(
 "unable to write the directory (written %zd/%zd)", bytes_written,
-directory_size);
+DIRECTORY_SIZE);
   return error;
 }
   }
 
   return error;
 }
 
-size_t MinidumpFileBuilder::GetDirectoriesNum() const {
-  return m_directories.size();
+static size_t GetLargestRange(const Process::CoreFileMemoryRanges ) {
+  size_t max_size = 0;
+  for (const auto _range : ranges)
+max_size = std::max(max_size, core_range.range.size());
+  return max_size;
 }
 
-size_t MinidumpFileBuilder::GetCurrentDataEndOffset() const {
-  return sizeof(llvm::minidump::Header) + m_data.GetByteSize();
+Status
+MinidumpFileBuilder::AddMemoryList_32(Process::CoreFileMemoryRanges ) {
+  std::vector descriptors;
+  Status error;
+  if (ranges.size() == 0)
+return error;
+
+  Log *log = GetLog(LLDBLog::Object);
+  size_t region_index = 0;
+  auto data_up = std::make_unique(GetLargestRange(ranges), 0);
+  for (const auto _range : ranges) {
+// Take the offset before we write.
+const size_t offset_for_data = GetCurrentDataEndOffset();
+const addr_t addr = core_range.range.start();
+const addr_t size = core_range.range.size();
+const addr_t end = core_range.range.end();
+
+LLDB_LOGF(log,
+  "AddMemoryList %zu/%zu reading memory for region "
+  "(%zu bytes) [%zx, %zx)",
+  region_index, ranges.size(), size, addr, addr + size);
+++region_index;
+
+const size_t bytes_read =
+m_process_sp->ReadMemory(addr, data_up->GetBytes(), size, error);
+if (error.Fail() || bytes_read == 0) {
+  LLDB_LOGF(log, "Failed to read memory region. Bytes read: %zu, error: 
%s",
+bytes_read, error.AsCString());
+  // Just skip sections with errors or zero bytes in 32b mode
+  continue;
+} else if (bytes_read != size) {
+  LLDB_LOGF(log, "Memory region at: %zu failed to read %zu bytes", addr,
+size);
+}
+
+MemoryDescriptor descriptor;
+descriptor.StartOfMemoryRange =
+static_cast(addr);
+descriptor.Memory.DataSize =
+static_cast(bytes_read);
+descriptor.Memory.RVA =
+static_cast(offset_for_data);
+descriptors.push_back(descriptor);
+if (m_thread_by_range_end.count(end) > 0)
+  m_thread_by_range_end[end].Stack = descriptor;
+
+// Add the data to the buffer, flush as needed.
+error = AddData(data_up->GetBytes(), bytes_read);
+if (error.Fail())
+  return error;
+  }
+
+  // Add a directory that references this list
+  // With a size of the number of ranges as a 32 bit num
+  // And then the size of all the ranges
+  error = AddDirectory(StreamType::MemoryList,
+   sizeof(llvm::support::ulittle32_t) +
+   descriptors.size() *
+   sizeof(llvm::minidump::MemoryDescriptor));
+  if (error.Fail())
+return error;
+
+  llvm::support::ulittle32_t memory_ranges_num =
+  static_cast(descriptors.size());
+  

[Lldb-commits] [lldb] [llvm] [LLDB][Minidump] Add 64b support to LLDB's minidump file builder. (PR #95312)

2024-06-17 Thread Greg Clayton via lldb-commits


@@ -791,26 +805,99 @@ void MinidumpFileBuilder::AddLinuxFileStreams(
   size_t size = memory_buffer->getBufferSize();
   if (size == 0)
 continue;
-  AddDirectory(stream, size);
+  error = AddDirectory(stream, size);
+  if (error.Fail())
+return error;
   m_data.AppendData(memory_buffer->getBufferStart(), size);
 }
   }
+
+  return error;
 }
 
-Status MinidumpFileBuilder::Dump(lldb::FileUP _file) const {
-  constexpr size_t header_size = sizeof(llvm::minidump::Header);
-  constexpr size_t directory_size = sizeof(llvm::minidump::Directory);
+Status MinidumpFileBuilder::AddMemoryList(SaveCoreStyle core_style) {
+  Status error;
+
+  Process::CoreFileMemoryRanges ranges_32;
+  Process::CoreFileMemoryRanges ranges_64;
+  error = m_process_sp->CalculateCoreFileSaveRanges(
+  SaveCoreStyle::eSaveCoreStackOnly, ranges_32);
+  if (error.Fail())
+return error;
+
+  uint64_t total_size =
+  ranges_32.size() * sizeof(llvm::minidump::MemoryDescriptor);
+  std::unordered_set stack_start_addresses;
+  for (const auto _range : ranges_32) {
+stack_start_addresses.insert(core_range.range.start());
+total_size += core_range.range.size();
+  }
+
+  if (total_size >= UINT32_MAX) {
+error.SetErrorStringWithFormat("Unable to write minidump. Stack memory "
+   "exceeds 32b limit. (Num Stacks %zu)",
+   ranges_32.size());
+return error;
+  }
+
+  Process::CoreFileMemoryRanges all_core_memory_ranges;
+  if (core_style != SaveCoreStyle::eSaveCoreStackOnly) {
+error = m_process_sp->CalculateCoreFileSaveRanges(core_style,
+  all_core_memory_ranges);
+if (error.Fail())
+  return error;
+  }
+
+  // We need to calculate the MemoryDescriptor size in the worst case
+  // Where all memory descriptors are 64b. We also leave some additional 
padding
+  // So that we convert over to 64b with space to spare. This does not waste
+  // space in the dump But instead converts some memory from being in the
+  // memorylist_32 to the memorylist_64.
+  total_size +=
+  256 + (all_core_memory_ranges.size() - stack_start_addresses.size()) *
+sizeof(llvm::minidump::MemoryDescriptor_64);
+
+  for (const auto _range : all_core_memory_ranges) {
+addr_t size_to_add =
+core_range.range.size() + sizeof(llvm::minidump::MemoryDescriptor);

clayborg wrote:

Remove `sizeof(llvm::minidump::MemoryDescriptor)` from here since we account 
for it before this for loop. If this is now just the core range size, rename 
like `range_size`

https://github.com/llvm/llvm-project/pull/95312
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [llvm] [LLDB][Minidump] Add 64b support to LLDB's minidump file builder. (PR #95312)

2024-06-17 Thread Greg Clayton via lldb-commits


@@ -821,47 +908,285 @@ Status MinidumpFileBuilder::Dump(lldb::FileUP 
_file) const {
   Status error;
   size_t bytes_written;
 
-  bytes_written = header_size;
-  error = core_file->Write(, bytes_written);
-  if (error.Fail() || bytes_written != header_size) {
-if (bytes_written != header_size)
+  m_core_file->SeekFromStart(0);
+  bytes_written = HEADER_SIZE;
+  error = m_core_file->Write(, bytes_written);
+  if (error.Fail() || bytes_written != HEADER_SIZE) {
+if (bytes_written != HEADER_SIZE)
   error.SetErrorStringWithFormat(
-  "unable to write the header (written %zd/%zd)", bytes_written,
-  header_size);
+  "Unable to write the minidump header (written %zd/%zd)",
+  bytes_written, HEADER_SIZE);
 return error;
   }
+  return error;
+}
 
-  // write data
-  bytes_written = m_data.GetByteSize();
-  error = core_file->Write(m_data.GetBytes(), bytes_written);
-  if (error.Fail() || bytes_written != m_data.GetByteSize()) {
-if (bytes_written != m_data.GetByteSize())
-  error.SetErrorStringWithFormat(
-  "unable to write the data (written %zd/%" PRIu64 ")", bytes_written,
-  m_data.GetByteSize());
-return error;
-  }
+size_t MinidumpFileBuilder::GetCurrentDataEndOffset() const {
+  return m_data.GetByteSize() + m_saved_data_size;
+}
 
-  // write directories
+Status MinidumpFileBuilder::DumpDirectories() const {
+  Status error;
+  size_t bytes_written;
+  m_core_file->SeekFromStart(HEADER_SIZE);
   for (const Directory  : m_directories) {
-bytes_written = directory_size;
-error = core_file->Write(, bytes_written);
-if (error.Fail() || bytes_written != directory_size) {
-  if (bytes_written != directory_size)
+bytes_written = DIRECTORY_SIZE;
+error = m_core_file->Write(, bytes_written);
+if (error.Fail() || bytes_written != DIRECTORY_SIZE) {
+  if (bytes_written != DIRECTORY_SIZE)
 error.SetErrorStringWithFormat(
 "unable to write the directory (written %zd/%zd)", bytes_written,
-directory_size);
+DIRECTORY_SIZE);
   return error;
 }
   }
 
   return error;
 }
 
-size_t MinidumpFileBuilder::GetDirectoriesNum() const {
-  return m_directories.size();
+static size_t GetLargestRange(const Process::CoreFileMemoryRanges ) {
+  size_t max_size = 0;
+  for (const auto _range : ranges)
+max_size = std::max(max_size, core_range.range.size());
+  return max_size;
 }
 
-size_t MinidumpFileBuilder::GetCurrentDataEndOffset() const {
-  return sizeof(llvm::minidump::Header) + m_data.GetByteSize();
+Status
+MinidumpFileBuilder::AddMemoryList_32(Process::CoreFileMemoryRanges ) {
+  std::vector descriptors;
+  Status error;
+  if (ranges.size() == 0)
+return error;
+
+  Log *log = GetLog(LLDBLog::Object);
+  size_t region_index = 0;
+  auto data_up = std::make_unique(GetLargestRange(ranges), 0);
+  for (const auto _range : ranges) {
+// Take the offset before we write.
+const size_t offset_for_data = GetCurrentDataEndOffset();
+const addr_t addr = core_range.range.start();
+const addr_t size = core_range.range.size();
+const addr_t end = core_range.range.end();
+
+LLDB_LOGF(log,
+  "AddMemoryList %zu/%zu reading memory for region "
+  "(%zu bytes) [%zx, %zx)",
+  region_index, ranges.size(), size, addr, addr + size);
+++region_index;
+
+const size_t bytes_read =
+m_process_sp->ReadMemory(addr, data_up->GetBytes(), size, error);
+if (error.Fail() || bytes_read == 0) {
+  LLDB_LOGF(log, "Failed to read memory region. Bytes read: %zu, error: 
%s",
+bytes_read, error.AsCString());
+  // Just skip sections with errors or zero bytes in 32b mode
+  continue;
+} else if (bytes_read != size) {
+  LLDB_LOGF(log, "Memory region at: %zu failed to read %zu bytes", addr,
+size);
+}
+
+MemoryDescriptor descriptor;
+descriptor.StartOfMemoryRange =
+static_cast(addr);
+descriptor.Memory.DataSize =
+static_cast(bytes_read);
+descriptor.Memory.RVA =
+static_cast(offset_for_data);
+descriptors.push_back(descriptor);
+if (m_thread_by_range_end.count(end) > 0)
+  m_thread_by_range_end[end].Stack = descriptor;
+
+// Add the data to the buffer, flush as needed.
+error = AddData(data_up->GetBytes(), bytes_read);
+if (error.Fail())
+  return error;
+  }
+
+  // Add a directory that references this list
+  // With a size of the number of ranges as a 32 bit num
+  // And then the size of all the ranges
+  error = AddDirectory(StreamType::MemoryList,
+   sizeof(llvm::support::ulittle32_t) +
+   descriptors.size() *
+   sizeof(llvm::minidump::MemoryDescriptor));
+  if (error.Fail())
+return error;
+
+  llvm::support::ulittle32_t memory_ranges_num =
+  static_cast(descriptors.size());
+  

[Lldb-commits] [lldb] [llvm] [LLDB][Minidump] Add 64b support to LLDB's minidump file builder. (PR #95312)

2024-06-17 Thread Greg Clayton via lldb-commits


@@ -480,71 +559,64 @@ class ArchThreadContexts {
   }
 };
 
-// Function returns start and size of the memory region that contains
-// memory location pointed to by the current stack pointer.
-llvm::Expected>
-findStackHelper(const lldb::ProcessSP _sp, uint64_t rsp) {
-  MemoryRegionInfo range_info;
-  Status error = process_sp->GetMemoryRegionInfo(rsp, range_info);
-  // Skip failed memory region requests or any regions with no permissions.
-  if (error.Fail() || range_info.GetLLDBPermissions() == 0)
-return llvm::createStringError(
-std::errc::not_supported,
-"unable to load stack segment of the process");
-
-  // This is a duplicate of the logic in
-  // Process::SaveOffRegionsWithStackPointers but ultimately, we need to only
-  // save up from the start of the stack down to the stack pointer
-  const addr_t range_end = range_info.GetRange().GetRangeEnd();
-  const addr_t red_zone = process_sp->GetABI()->GetRedZoneSize();
-  const addr_t stack_head = rsp - red_zone;
-  if (stack_head > range_info.GetRange().GetRangeEnd()) {
-range_info.GetRange().SetRangeBase(stack_head);
-range_info.GetRange().SetByteSize(range_end - stack_head);
-  }
-
-  const addr_t addr = range_info.GetRange().GetRangeBase();
-  const addr_t size = range_info.GetRange().GetByteSize();
-
-  if (size == 0)
-return llvm::createStringError(std::errc::not_supported,
-   "stack segment of the process is empty");
-
-  return std::make_pair(addr, size);
+Status MinidumpFileBuilder::FixThreadStacks() {
+  Status error;
+  // If we have anything in the heap flush it.
+  FlushBufferToDisk();
+  m_core_file->SeekFromStart(m_thread_list_start);
+  for (auto  : m_thread_by_range_end) {
+// The thread objects will get a new memory descriptor added
+// When we are emitting the memory list and then we write it here
+const llvm::minidump::Thread  = pair.second;
+size_t bytes_to_write = sizeof(llvm::minidump::Thread);
+size_t bytes_written = bytes_to_write;
+error = m_core_file->Write(, bytes_written);

clayborg wrote:

We can do this in a later patch as the `sizeof(llvm::minidump::Thread)` won't 
exceed 32 bits


https://github.com/llvm/llvm-project/pull/95312
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [llvm] [LLDB][Minidump] Add 64b support to LLDB's minidump file builder. (PR #95312)

2024-06-17 Thread Greg Clayton via lldb-commits


@@ -821,47 +908,285 @@ Status MinidumpFileBuilder::Dump(lldb::FileUP 
_file) const {
   Status error;
   size_t bytes_written;
 
-  bytes_written = header_size;
-  error = core_file->Write(, bytes_written);
-  if (error.Fail() || bytes_written != header_size) {
-if (bytes_written != header_size)
+  m_core_file->SeekFromStart(0);
+  bytes_written = HEADER_SIZE;
+  error = m_core_file->Write(, bytes_written);
+  if (error.Fail() || bytes_written != HEADER_SIZE) {
+if (bytes_written != HEADER_SIZE)
   error.SetErrorStringWithFormat(
-  "unable to write the header (written %zd/%zd)", bytes_written,
-  header_size);
+  "Unable to write the minidump header (written %zd/%zd)",
+  bytes_written, HEADER_SIZE);
 return error;
   }
+  return error;
+}
 
-  // write data
-  bytes_written = m_data.GetByteSize();
-  error = core_file->Write(m_data.GetBytes(), bytes_written);
-  if (error.Fail() || bytes_written != m_data.GetByteSize()) {
-if (bytes_written != m_data.GetByteSize())
-  error.SetErrorStringWithFormat(
-  "unable to write the data (written %zd/%" PRIu64 ")", bytes_written,
-  m_data.GetByteSize());
-return error;
-  }
+size_t MinidumpFileBuilder::GetCurrentDataEndOffset() const {
+  return m_data.GetByteSize() + m_saved_data_size;
+}
 
-  // write directories
+Status MinidumpFileBuilder::DumpDirectories() const {
+  Status error;
+  size_t bytes_written;
+  m_core_file->SeekFromStart(HEADER_SIZE);
   for (const Directory  : m_directories) {
-bytes_written = directory_size;
-error = core_file->Write(, bytes_written);
-if (error.Fail() || bytes_written != directory_size) {
-  if (bytes_written != directory_size)
+bytes_written = DIRECTORY_SIZE;
+error = m_core_file->Write(, bytes_written);
+if (error.Fail() || bytes_written != DIRECTORY_SIZE) {
+  if (bytes_written != DIRECTORY_SIZE)
 error.SetErrorStringWithFormat(
 "unable to write the directory (written %zd/%zd)", bytes_written,
-directory_size);
+DIRECTORY_SIZE);
   return error;
 }
   }
 
   return error;
 }
 
-size_t MinidumpFileBuilder::GetDirectoriesNum() const {
-  return m_directories.size();
+static size_t GetLargestRange(const Process::CoreFileMemoryRanges ) {
+  size_t max_size = 0;
+  for (const auto _range : ranges)
+max_size = std::max(max_size, core_range.range.size());
+  return max_size;
 }
 
-size_t MinidumpFileBuilder::GetCurrentDataEndOffset() const {
-  return sizeof(llvm::minidump::Header) + m_data.GetByteSize();
+Status
+MinidumpFileBuilder::AddMemoryList_32(Process::CoreFileMemoryRanges ) {
+  std::vector descriptors;
+  Status error;
+  if (ranges.size() == 0)
+return error;
+
+  Log *log = GetLog(LLDBLog::Object);
+  size_t region_index = 0;
+  auto data_up = std::make_unique(GetLargestRange(ranges), 0);
+  for (const auto _range : ranges) {
+// Take the offset before we write.
+const size_t offset_for_data = GetCurrentDataEndOffset();
+const addr_t addr = core_range.range.start();
+const addr_t size = core_range.range.size();
+const addr_t end = core_range.range.end();
+
+LLDB_LOGF(log,
+  "AddMemoryList %zu/%zu reading memory for region "
+  "(%zu bytes) [%zx, %zx)",

clayborg wrote:

Change `"(%zu bytes) [%zx, %zx)"` to `"(%" PRIu64 " bytes [%" PRIx64 ", %" 
PRIx64 ")"`

https://github.com/llvm/llvm-project/pull/95312
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [llvm] [LLDB][Minidump] Add 64b support to LLDB's minidump file builder. (PR #95312)

2024-06-17 Thread Greg Clayton via lldb-commits


@@ -821,47 +908,285 @@ Status MinidumpFileBuilder::Dump(lldb::FileUP 
_file) const {
   Status error;
   size_t bytes_written;
 
-  bytes_written = header_size;
-  error = core_file->Write(, bytes_written);
-  if (error.Fail() || bytes_written != header_size) {
-if (bytes_written != header_size)
+  m_core_file->SeekFromStart(0);
+  bytes_written = HEADER_SIZE;
+  error = m_core_file->Write(, bytes_written);
+  if (error.Fail() || bytes_written != HEADER_SIZE) {
+if (bytes_written != HEADER_SIZE)
   error.SetErrorStringWithFormat(
-  "unable to write the header (written %zd/%zd)", bytes_written,
-  header_size);
+  "Unable to write the minidump header (written %zd/%zd)",
+  bytes_written, HEADER_SIZE);
 return error;
   }
+  return error;
+}
 
-  // write data
-  bytes_written = m_data.GetByteSize();
-  error = core_file->Write(m_data.GetBytes(), bytes_written);
-  if (error.Fail() || bytes_written != m_data.GetByteSize()) {
-if (bytes_written != m_data.GetByteSize())
-  error.SetErrorStringWithFormat(
-  "unable to write the data (written %zd/%" PRIu64 ")", bytes_written,
-  m_data.GetByteSize());
-return error;
-  }
+size_t MinidumpFileBuilder::GetCurrentDataEndOffset() const {
+  return m_data.GetByteSize() + m_saved_data_size;
+}
 
-  // write directories
+Status MinidumpFileBuilder::DumpDirectories() const {
+  Status error;
+  size_t bytes_written;
+  m_core_file->SeekFromStart(HEADER_SIZE);
   for (const Directory  : m_directories) {
-bytes_written = directory_size;
-error = core_file->Write(, bytes_written);
-if (error.Fail() || bytes_written != directory_size) {
-  if (bytes_written != directory_size)
+bytes_written = DIRECTORY_SIZE;
+error = m_core_file->Write(, bytes_written);
+if (error.Fail() || bytes_written != DIRECTORY_SIZE) {
+  if (bytes_written != DIRECTORY_SIZE)
 error.SetErrorStringWithFormat(
 "unable to write the directory (written %zd/%zd)", bytes_written,
-directory_size);
+DIRECTORY_SIZE);
   return error;
 }
   }
 
   return error;
 }
 
-size_t MinidumpFileBuilder::GetDirectoriesNum() const {
-  return m_directories.size();
+static size_t GetLargestRange(const Process::CoreFileMemoryRanges ) {
+  size_t max_size = 0;
+  for (const auto _range : ranges)
+max_size = std::max(max_size, core_range.range.size());
+  return max_size;
 }
 
-size_t MinidumpFileBuilder::GetCurrentDataEndOffset() const {
-  return sizeof(llvm::minidump::Header) + m_data.GetByteSize();
+Status
+MinidumpFileBuilder::AddMemoryList_32(Process::CoreFileMemoryRanges ) {
+  std::vector descriptors;
+  Status error;
+  if (ranges.size() == 0)
+return error;
+
+  Log *log = GetLog(LLDBLog::Object);
+  size_t region_index = 0;
+  auto data_up = std::make_unique(GetLargestRange(ranges), 0);
+  for (const auto _range : ranges) {
+// Take the offset before we write.
+const size_t offset_for_data = GetCurrentDataEndOffset();

clayborg wrote:

uint64_t

https://github.com/llvm/llvm-project/pull/95312
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [llvm] [LLDB][Minidump] Add 64b support to LLDB's minidump file builder. (PR #95312)

2024-06-17 Thread Greg Clayton via lldb-commits


@@ -858,10 +953,247 @@ Status MinidumpFileBuilder::Dump(lldb::FileUP 
_file) const {
   return error;
 }
 
-size_t MinidumpFileBuilder::GetDirectoriesNum() const {
-  return m_directories.size();
+static size_t GetLargestRange(const Process::CoreFileMemoryRanges ) {
+  size_t max_size = 0;
+  for (const auto _range : ranges) {
+max_size = std::max(max_size, core_range.range.size());
+  }
+  return max_size;
 }
 
-size_t MinidumpFileBuilder::GetCurrentDataEndOffset() const {
-  return sizeof(llvm::minidump::Header) + m_data.GetByteSize();
+Status MinidumpFileBuilder::AddMemoryList_32(
+  Process::CoreFileMemoryRanges ) {
+  std::vector descriptors;
+  Status error;
+  if (ranges.size() == 0)
+return error;
+
+  Log *log = GetLog(LLDBLog::Object);
+  size_t region_index = 0;
+  auto data_up = std::make_unique(GetLargestRange(ranges), 0);
+  for (const auto _range : ranges) {
+// Take the offset before we write.
+const size_t offset_for_data = GetCurrentDataEndOffset();
+const addr_t addr = core_range.range.start();
+const addr_t size = core_range.range.size();
+const addr_t end = core_range.range.end();
+
+LLDB_LOGF(log,
+  "AddMemoryList %zu/%zu reading memory for region "
+  "(%zu bytes) [%zx, %zx)",
+  region_index, ranges.size(), size, addr, addr + size);
+++region_index;
+
+const size_t bytes_read =
+m_process_sp->ReadMemory(addr, data_up->GetBytes(), size, error);
+if (error.Fail() || bytes_read == 0) {
+  LLDB_LOGF(log, "Failed to read memory region. Bytes read: %zu, error: 
%s",
+bytes_read, error.AsCString());
+  // Just skip sections with errors or zero bytes in 32b mode
+  continue;
+} else if (bytes_read != size) {
+  LLDB_LOGF(log, "Memory region at: %zu failed to read %zu bytes", addr,
+size);
+}
+
+MemoryDescriptor descriptor;
+descriptor.StartOfMemoryRange =
+static_cast(addr);
+descriptor.Memory.DataSize =
+static_cast(bytes_read);
+descriptor.Memory.RVA =
+static_cast(offset_for_data);

clayborg wrote:

remove static_casts

https://github.com/llvm/llvm-project/pull/95312
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [llvm] [LLDB][Minidump] Add 64b support to LLDB's minidump file builder. (PR #95312)

2024-06-17 Thread Greg Clayton via lldb-commits


@@ -821,47 +908,285 @@ Status MinidumpFileBuilder::Dump(lldb::FileUP 
_file) const {
   Status error;
   size_t bytes_written;
 
-  bytes_written = header_size;
-  error = core_file->Write(, bytes_written);
-  if (error.Fail() || bytes_written != header_size) {
-if (bytes_written != header_size)
+  m_core_file->SeekFromStart(0);
+  bytes_written = HEADER_SIZE;
+  error = m_core_file->Write(, bytes_written);
+  if (error.Fail() || bytes_written != HEADER_SIZE) {
+if (bytes_written != HEADER_SIZE)
   error.SetErrorStringWithFormat(
-  "unable to write the header (written %zd/%zd)", bytes_written,
-  header_size);
+  "Unable to write the minidump header (written %zd/%zd)",
+  bytes_written, HEADER_SIZE);
 return error;
   }
+  return error;
+}
 
-  // write data
-  bytes_written = m_data.GetByteSize();
-  error = core_file->Write(m_data.GetBytes(), bytes_written);
-  if (error.Fail() || bytes_written != m_data.GetByteSize()) {
-if (bytes_written != m_data.GetByteSize())
-  error.SetErrorStringWithFormat(
-  "unable to write the data (written %zd/%" PRIu64 ")", bytes_written,
-  m_data.GetByteSize());
-return error;
-  }
+size_t MinidumpFileBuilder::GetCurrentDataEndOffset() const {
+  return m_data.GetByteSize() + m_saved_data_size;
+}
 
-  // write directories
+Status MinidumpFileBuilder::DumpDirectories() const {
+  Status error;
+  size_t bytes_written;
+  m_core_file->SeekFromStart(HEADER_SIZE);
   for (const Directory  : m_directories) {
-bytes_written = directory_size;
-error = core_file->Write(, bytes_written);
-if (error.Fail() || bytes_written != directory_size) {
-  if (bytes_written != directory_size)
+bytes_written = DIRECTORY_SIZE;
+error = m_core_file->Write(, bytes_written);
+if (error.Fail() || bytes_written != DIRECTORY_SIZE) {
+  if (bytes_written != DIRECTORY_SIZE)
 error.SetErrorStringWithFormat(
 "unable to write the directory (written %zd/%zd)", bytes_written,
-directory_size);
+DIRECTORY_SIZE);
   return error;
 }
   }
 
   return error;
 }
 
-size_t MinidumpFileBuilder::GetDirectoriesNum() const {
-  return m_directories.size();
+static size_t GetLargestRange(const Process::CoreFileMemoryRanges ) {
+  size_t max_size = 0;

clayborg wrote:

use `uint64_t`

https://github.com/llvm/llvm-project/pull/95312
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [llvm] [LLDB][Minidump] Add 64b support to LLDB's minidump file builder. (PR #95312)

2024-06-17 Thread Greg Clayton via lldb-commits


@@ -821,47 +908,285 @@ Status MinidumpFileBuilder::Dump(lldb::FileUP 
_file) const {
   Status error;
   size_t bytes_written;
 
-  bytes_written = header_size;
-  error = core_file->Write(, bytes_written);
-  if (error.Fail() || bytes_written != header_size) {
-if (bytes_written != header_size)
+  m_core_file->SeekFromStart(0);
+  bytes_written = HEADER_SIZE;
+  error = m_core_file->Write(, bytes_written);
+  if (error.Fail() || bytes_written != HEADER_SIZE) {
+if (bytes_written != HEADER_SIZE)
   error.SetErrorStringWithFormat(
-  "unable to write the header (written %zd/%zd)", bytes_written,
-  header_size);
+  "Unable to write the minidump header (written %zd/%zd)",
+  bytes_written, HEADER_SIZE);
 return error;
   }
+  return error;
+}
 
-  // write data
-  bytes_written = m_data.GetByteSize();
-  error = core_file->Write(m_data.GetBytes(), bytes_written);
-  if (error.Fail() || bytes_written != m_data.GetByteSize()) {
-if (bytes_written != m_data.GetByteSize())
-  error.SetErrorStringWithFormat(
-  "unable to write the data (written %zd/%" PRIu64 ")", bytes_written,
-  m_data.GetByteSize());
-return error;
-  }
+size_t MinidumpFileBuilder::GetCurrentDataEndOffset() const {
+  return m_data.GetByteSize() + m_saved_data_size;
+}
 
-  // write directories
+Status MinidumpFileBuilder::DumpDirectories() const {
+  Status error;
+  size_t bytes_written;
+  m_core_file->SeekFromStart(HEADER_SIZE);
   for (const Directory  : m_directories) {
-bytes_written = directory_size;
-error = core_file->Write(, bytes_written);
-if (error.Fail() || bytes_written != directory_size) {
-  if (bytes_written != directory_size)
+bytes_written = DIRECTORY_SIZE;
+error = m_core_file->Write(, bytes_written);
+if (error.Fail() || bytes_written != DIRECTORY_SIZE) {
+  if (bytes_written != DIRECTORY_SIZE)
 error.SetErrorStringWithFormat(
 "unable to write the directory (written %zd/%zd)", bytes_written,
-directory_size);
+DIRECTORY_SIZE);
   return error;
 }
   }
 
   return error;
 }
 
-size_t MinidumpFileBuilder::GetDirectoriesNum() const {
-  return m_directories.size();
+static size_t GetLargestRange(const Process::CoreFileMemoryRanges ) {

clayborg wrote:

Rename to match what it is returning and don't use `size_t`, this will fail on 
32 bit systems if we have a range over UINT32_MAX:
```
static uint64_t GetLargestRangeSize(const Process::CoreFileMemoryRanges 
) {

https://github.com/llvm/llvm-project/pull/95312
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [llvm] [LLDB][Minidump] Add 64b support to LLDB's minidump file builder. (PR #95312)

2024-06-17 Thread Greg Clayton via lldb-commits


@@ -791,26 +805,99 @@ void MinidumpFileBuilder::AddLinuxFileStreams(
   size_t size = memory_buffer->getBufferSize();
   if (size == 0)
 continue;
-  AddDirectory(stream, size);
+  error = AddDirectory(stream, size);
+  if (error.Fail())
+return error;
   m_data.AppendData(memory_buffer->getBufferStart(), size);
 }
   }
+
+  return error;
 }
 
-Status MinidumpFileBuilder::Dump(lldb::FileUP _file) const {
-  constexpr size_t header_size = sizeof(llvm::minidump::Header);
-  constexpr size_t directory_size = sizeof(llvm::minidump::Directory);
+Status MinidumpFileBuilder::AddMemoryList(SaveCoreStyle core_style) {
+  Status error;
+
+  Process::CoreFileMemoryRanges ranges_32;
+  Process::CoreFileMemoryRanges ranges_64;
+  error = m_process_sp->CalculateCoreFileSaveRanges(
+  SaveCoreStyle::eSaveCoreStackOnly, ranges_32);
+  if (error.Fail())
+return error;
+
+  uint64_t total_size =
+  ranges_32.size() * sizeof(llvm::minidump::MemoryDescriptor);
+  std::unordered_set stack_start_addresses;
+  for (const auto _range : ranges_32) {
+stack_start_addresses.insert(core_range.range.start());
+total_size += core_range.range.size();
+  }
+
+  if (total_size >= UINT32_MAX) {
+error.SetErrorStringWithFormat("Unable to write minidump. Stack memory "
+   "exceeds 32b limit. (Num Stacks %zu)",
+   ranges_32.size());
+return error;
+  }
+
+  Process::CoreFileMemoryRanges all_core_memory_ranges;
+  if (core_style != SaveCoreStyle::eSaveCoreStackOnly) {
+error = m_process_sp->CalculateCoreFileSaveRanges(core_style,
+  all_core_memory_ranges);
+if (error.Fail())
+  return error;
+  }
+
+  // We need to calculate the MemoryDescriptor size in the worst case
+  // Where all memory descriptors are 64b. We also leave some additional 
padding
+  // So that we convert over to 64b with space to spare. This does not waste
+  // space in the dump But instead converts some memory from being in the
+  // memorylist_32 to the memorylist_64.
+  total_size +=
+  256 + (all_core_memory_ranges.size() - stack_start_addresses.size()) *
+sizeof(llvm::minidump::MemoryDescriptor_64);
+
+  for (const auto _range : all_core_memory_ranges) {
+addr_t size_to_add =
+core_range.range.size() + sizeof(llvm::minidump::MemoryDescriptor);
+if (stack_start_addresses.count(core_range.range.start()) > 0)
+  // Don't double save stacks.
+  continue;
+
+if (total_size + size_to_add < UINT32_MAX) {
+  ranges_32.push_back(core_range);
+  total_size += core_range.range.size();
+} else {
+  ranges_64.push_back(core_range);
+}
+  }
+
+  error = AddMemoryList_32(ranges_32);
+  if (error.Fail())
+return error;
+
+  // Add the remaining memory as a 64b range.
+  if (!ranges_64.empty()) {
+error = AddMemoryList_64(ranges_64);
+if (error.Fail())
+  return error;
+  }
 
+  return FixThreadStacks();
+}
+
+Status MinidumpFileBuilder::DumpHeader() const {
   // write header
   llvm::minidump::Header header;
   header.Signature = static_cast(
   llvm::minidump::Header::MagicSignature);
   header.Version = static_cast(
   llvm::minidump::Header::MagicVersion);
   header.NumberOfStreams =
-  static_cast(GetDirectoriesNum());
+  static_cast(m_directories.size());
+  // We write the directories right after the header.
   header.StreamDirectoryRVA =
-  static_cast(GetCurrentDataEndOffset());
+  static_cast(HEADER_SIZE);

clayborg wrote:

remove static_cast, not needed.

https://github.com/llvm/llvm-project/pull/95312
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [llvm] [LLDB][Minidump] Add 64b support to LLDB's minidump file builder. (PR #95312)

2024-06-17 Thread Greg Clayton via lldb-commits


@@ -858,10 +953,247 @@ Status MinidumpFileBuilder::Dump(lldb::FileUP 
_file) const {
   return error;
 }
 
-size_t MinidumpFileBuilder::GetDirectoriesNum() const {
-  return m_directories.size();
+static size_t GetLargestRange(const Process::CoreFileMemoryRanges ) {
+  size_t max_size = 0;
+  for (const auto _range : ranges) {
+max_size = std::max(max_size, core_range.range.size());
+  }
+  return max_size;
 }
 
-size_t MinidumpFileBuilder::GetCurrentDataEndOffset() const {
-  return sizeof(llvm::minidump::Header) + m_data.GetByteSize();
+Status MinidumpFileBuilder::AddMemoryList_32(
+  Process::CoreFileMemoryRanges ) {
+  std::vector descriptors;
+  Status error;
+  if (ranges.size() == 0)
+return error;
+
+  Log *log = GetLog(LLDBLog::Object);
+  size_t region_index = 0;
+  auto data_up = std::make_unique(GetLargestRange(ranges), 0);
+  for (const auto _range : ranges) {
+// Take the offset before we write.
+const size_t offset_for_data = GetCurrentDataEndOffset();
+const addr_t addr = core_range.range.start();
+const addr_t size = core_range.range.size();
+const addr_t end = core_range.range.end();
+
+LLDB_LOGF(log,
+  "AddMemoryList %zu/%zu reading memory for region "
+  "(%zu bytes) [%zx, %zx)",
+  region_index, ranges.size(), size, addr, addr + size);
+++region_index;
+
+const size_t bytes_read =
+m_process_sp->ReadMemory(addr, data_up->GetBytes(), size, error);
+if (error.Fail() || bytes_read == 0) {
+  LLDB_LOGF(log, "Failed to read memory region. Bytes read: %zu, error: 
%s",
+bytes_read, error.AsCString());
+  // Just skip sections with errors or zero bytes in 32b mode
+  continue;
+} else if (bytes_read != size) {
+  LLDB_LOGF(log, "Memory region at: %zu failed to read %zu bytes", addr,
+size);
+}
+
+MemoryDescriptor descriptor;
+descriptor.StartOfMemoryRange =
+static_cast(addr);
+descriptor.Memory.DataSize =
+static_cast(bytes_read);
+descriptor.Memory.RVA =
+static_cast(offset_for_data);
+descriptors.push_back(descriptor);
+if (m_thread_by_range_end.count(end) > 0)
+  m_thread_by_range_end[end].Stack = descriptor;
+
+// Add the data to the buffer, flush as needed.
+error = AddData(data_up->GetBytes(), bytes_read);
+if (error.Fail())
+  return error;
+  }
+
+  // Add a directory that references this list
+  // With a size of the number of ranges as a 32 bit num
+  // And then the size of all the ranges
+  error = AddDirectory(StreamType::MemoryList,
+   sizeof(llvm::support::ulittle32_t) +
+   descriptors.size() *
+   sizeof(llvm::minidump::MemoryDescriptor));
+  if (error.Fail())
+return error;
+
+  llvm::support::ulittle32_t memory_ranges_num =
+  static_cast(descriptors.size());
+  m_data.AppendData(_ranges_num, sizeof(llvm::support::ulittle32_t));
+  // For 32b we can get away with writing off the descriptors after the data.
+  // This means no cleanup loop needed.
+  m_data.AppendData(descriptors.data(),
+descriptors.size() * sizeof(MemoryDescriptor));
+
+  return error;
+}
+
+Status MinidumpFileBuilder::AddMemoryList_64(
+Process::CoreFileMemoryRanges ) {
+  Status error;
+  if (ranges.empty()) 
+return error;
+
+  error = AddDirectory(StreamType::Memory64List,
+   (sizeof(llvm::support::ulittle64_t) * 2) +
+   ranges.size() * 
sizeof(llvm::minidump::MemoryDescriptor_64));
+  if (error.Fail())
+return error;
+
+  llvm::support::ulittle64_t memory_ranges_num =
+  static_cast(ranges.size());

clayborg wrote:

remove static casts

https://github.com/llvm/llvm-project/pull/95312
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [llvm] [LLDB][Minidump] Add 64b support to LLDB's minidump file builder. (PR #95312)

2024-06-17 Thread Greg Clayton via lldb-commits


@@ -480,71 +559,64 @@ class ArchThreadContexts {
   }
 };
 
-// Function returns start and size of the memory region that contains
-// memory location pointed to by the current stack pointer.
-llvm::Expected>
-findStackHelper(const lldb::ProcessSP _sp, uint64_t rsp) {
-  MemoryRegionInfo range_info;
-  Status error = process_sp->GetMemoryRegionInfo(rsp, range_info);
-  // Skip failed memory region requests or any regions with no permissions.
-  if (error.Fail() || range_info.GetLLDBPermissions() == 0)
-return llvm::createStringError(
-std::errc::not_supported,
-"unable to load stack segment of the process");
-
-  // This is a duplicate of the logic in
-  // Process::SaveOffRegionsWithStackPointers but ultimately, we need to only
-  // save up from the start of the stack down to the stack pointer
-  const addr_t range_end = range_info.GetRange().GetRangeEnd();
-  const addr_t red_zone = process_sp->GetABI()->GetRedZoneSize();
-  const addr_t stack_head = rsp - red_zone;
-  if (stack_head > range_info.GetRange().GetRangeEnd()) {
-range_info.GetRange().SetRangeBase(stack_head);
-range_info.GetRange().SetByteSize(range_end - stack_head);
-  }
-
-  const addr_t addr = range_info.GetRange().GetRangeBase();
-  const addr_t size = range_info.GetRange().GetByteSize();
-
-  if (size == 0)
-return llvm::createStringError(std::errc::not_supported,
-   "stack segment of the process is empty");
-
-  return std::make_pair(addr, size);
+Status MinidumpFileBuilder::FixThreadStacks() {
+  Status error;
+  // If we have anything in the heap flush it.
+  FlushBufferToDisk();
+  m_core_file->SeekFromStart(m_thread_list_start);
+  for (auto  : m_thread_by_range_end) {
+// The thread objects will get a new memory descriptor added
+// When we are emitting the memory list and then we write it here
+const llvm::minidump::Thread  = pair.second;
+size_t bytes_to_write = sizeof(llvm::minidump::Thread);
+size_t bytes_written = bytes_to_write;
+error = m_core_file->Write(, bytes_written);

clayborg wrote:

We should probably change the underlying `Write(...)` function to not use 
`size_t` if it is as this will fail on 32 bit architectures, or we need to 
write at most SIZET_MAX

https://github.com/llvm/llvm-project/pull/95312
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [llvm] [LLDB][Minidump] Add 64b support to LLDB's minidump file builder. (PR #95312)

2024-06-17 Thread Greg Clayton via lldb-commits


@@ -791,26 +805,99 @@ void MinidumpFileBuilder::AddLinuxFileStreams(
   size_t size = memory_buffer->getBufferSize();
   if (size == 0)
 continue;
-  AddDirectory(stream, size);
+  error = AddDirectory(stream, size);
+  if (error.Fail())
+return error;
   m_data.AppendData(memory_buffer->getBufferStart(), size);
 }
   }
+
+  return error;
 }
 
-Status MinidumpFileBuilder::Dump(lldb::FileUP _file) const {
-  constexpr size_t header_size = sizeof(llvm::minidump::Header);
-  constexpr size_t directory_size = sizeof(llvm::minidump::Directory);
+Status MinidumpFileBuilder::AddMemoryList(SaveCoreStyle core_style) {
+  Status error;
+
+  Process::CoreFileMemoryRanges ranges_32;
+  Process::CoreFileMemoryRanges ranges_64;
+  error = m_process_sp->CalculateCoreFileSaveRanges(
+  SaveCoreStyle::eSaveCoreStackOnly, ranges_32);
+  if (error.Fail())
+return error;
+
+  uint64_t total_size =
+  ranges_32.size() * sizeof(llvm::minidump::MemoryDescriptor);
+  std::unordered_set stack_start_addresses;
+  for (const auto _range : ranges_32) {
+stack_start_addresses.insert(core_range.range.start());
+total_size += core_range.range.size();
+  }
+
+  if (total_size >= UINT32_MAX) {
+error.SetErrorStringWithFormat("Unable to write minidump. Stack memory "
+   "exceeds 32b limit. (Num Stacks %zu)",
+   ranges_32.size());
+return error;
+  }
+
+  Process::CoreFileMemoryRanges all_core_memory_ranges;
+  if (core_style != SaveCoreStyle::eSaveCoreStackOnly) {
+error = m_process_sp->CalculateCoreFileSaveRanges(core_style,
+  all_core_memory_ranges);
+if (error.Fail())
+  return error;
+  }
+
+  // We need to calculate the MemoryDescriptor size in the worst case
+  // Where all memory descriptors are 64b. We also leave some additional 
padding
+  // So that we convert over to 64b with space to spare. This does not waste
+  // space in the dump But instead converts some memory from being in the
+  // memorylist_32 to the memorylist_64.
+  total_size +=
+  256 + (all_core_memory_ranges.size() - stack_start_addresses.size()) *
+sizeof(llvm::minidump::MemoryDescriptor_64);
+
+  for (const auto _range : all_core_memory_ranges) {
+addr_t size_to_add =
+core_range.range.size() + sizeof(llvm::minidump::MemoryDescriptor);
+if (stack_start_addresses.count(core_range.range.start()) > 0)
+  // Don't double save stacks.
+  continue;
+
+if (total_size + size_to_add < UINT32_MAX) {
+  ranges_32.push_back(core_range);
+  total_size += core_range.range.size();
+} else {
+  ranges_64.push_back(core_range);
+}
+  }
+
+  error = AddMemoryList_32(ranges_32);
+  if (error.Fail())
+return error;
+
+  // Add the remaining memory as a 64b range.
+  if (!ranges_64.empty()) {
+error = AddMemoryList_64(ranges_64);
+if (error.Fail())
+  return error;
+  }
 
+  return FixThreadStacks();
+}
+
+Status MinidumpFileBuilder::DumpHeader() const {
   // write header
   llvm::minidump::Header header;
   header.Signature = static_cast(
   llvm::minidump::Header::MagicSignature);
   header.Version = static_cast(
   llvm::minidump::Header::MagicVersion);
   header.NumberOfStreams =
-  static_cast(GetDirectoriesNum());
+  static_cast(m_directories.size());

clayborg wrote:

remove static_cast, not needed.

https://github.com/llvm/llvm-project/pull/95312
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [llvm] [LLDB][Minidump] Add 64b support to LLDB's minidump file builder. (PR #95312)

2024-06-17 Thread Greg Clayton via lldb-commits


@@ -858,10 +953,247 @@ Status MinidumpFileBuilder::Dump(lldb::FileUP 
_file) const {
   return error;
 }
 
-size_t MinidumpFileBuilder::GetDirectoriesNum() const {
-  return m_directories.size();
+static size_t GetLargestRange(const Process::CoreFileMemoryRanges ) {
+  size_t max_size = 0;
+  for (const auto _range : ranges) {
+max_size = std::max(max_size, core_range.range.size());
+  }
+  return max_size;
 }
 
-size_t MinidumpFileBuilder::GetCurrentDataEndOffset() const {
-  return sizeof(llvm::minidump::Header) + m_data.GetByteSize();
+Status MinidumpFileBuilder::AddMemoryList_32(
+  Process::CoreFileMemoryRanges ) {
+  std::vector descriptors;
+  Status error;
+  if (ranges.size() == 0)
+return error;
+
+  Log *log = GetLog(LLDBLog::Object);
+  size_t region_index = 0;
+  auto data_up = std::make_unique(GetLargestRange(ranges), 0);
+  for (const auto _range : ranges) {
+// Take the offset before we write.
+const size_t offset_for_data = GetCurrentDataEndOffset();
+const addr_t addr = core_range.range.start();
+const addr_t size = core_range.range.size();
+const addr_t end = core_range.range.end();
+
+LLDB_LOGF(log,
+  "AddMemoryList %zu/%zu reading memory for region "
+  "(%zu bytes) [%zx, %zx)",
+  region_index, ranges.size(), size, addr, addr + size);
+++region_index;
+
+const size_t bytes_read =
+m_process_sp->ReadMemory(addr, data_up->GetBytes(), size, error);
+if (error.Fail() || bytes_read == 0) {
+  LLDB_LOGF(log, "Failed to read memory region. Bytes read: %zu, error: 
%s",
+bytes_read, error.AsCString());
+  // Just skip sections with errors or zero bytes in 32b mode
+  continue;
+} else if (bytes_read != size) {
+  LLDB_LOGF(log, "Memory region at: %zu failed to read %zu bytes", addr,
+size);
+}
+
+MemoryDescriptor descriptor;
+descriptor.StartOfMemoryRange =
+static_cast(addr);
+descriptor.Memory.DataSize =
+static_cast(bytes_read);
+descriptor.Memory.RVA =
+static_cast(offset_for_data);
+descriptors.push_back(descriptor);
+if (m_thread_by_range_end.count(end) > 0)
+  m_thread_by_range_end[end].Stack = descriptor;
+
+// Add the data to the buffer, flush as needed.
+error = AddData(data_up->GetBytes(), bytes_read);
+if (error.Fail())
+  return error;
+  }
+
+  // Add a directory that references this list
+  // With a size of the number of ranges as a 32 bit num
+  // And then the size of all the ranges
+  error = AddDirectory(StreamType::MemoryList,
+   sizeof(llvm::support::ulittle32_t) +
+   descriptors.size() *
+   sizeof(llvm::minidump::MemoryDescriptor));
+  if (error.Fail())
+return error;
+
+  llvm::support::ulittle32_t memory_ranges_num =
+  static_cast(descriptors.size());

clayborg wrote:

The assignment operator can and must work for these 
`llvm::support::ulittleXX_t` values, we should take advantage of them and keep 
the code cleaner. Removing all static_casts makes this code easier to read and 
avoids people making copy/paste of similar code in the future. I know there 
were some static casts before this patch, but we should remove them.

https://github.com/llvm/llvm-project/pull/95312
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [llvm] [LLDB][Minidump] Add 64b support to LLDB's minidump file builder. (PR #95312)

2024-06-17 Thread Greg Clayton via lldb-commits


@@ -791,26 +805,99 @@ void MinidumpFileBuilder::AddLinuxFileStreams(
   size_t size = memory_buffer->getBufferSize();
   if (size == 0)
 continue;
-  AddDirectory(stream, size);
+  error = AddDirectory(stream, size);
+  if (error.Fail())
+return error;
   m_data.AppendData(memory_buffer->getBufferStart(), size);
 }
   }
+
+  return error;
 }
 
-Status MinidumpFileBuilder::Dump(lldb::FileUP _file) const {
-  constexpr size_t header_size = sizeof(llvm::minidump::Header);
-  constexpr size_t directory_size = sizeof(llvm::minidump::Directory);
+Status MinidumpFileBuilder::AddMemoryList(SaveCoreStyle core_style) {
+  Status error;
+
+  Process::CoreFileMemoryRanges ranges_32;
+  Process::CoreFileMemoryRanges ranges_64;
+  error = m_process_sp->CalculateCoreFileSaveRanges(

clayborg wrote:

Add a comment here:
```
// We first save the thread stacks to ensure they fit in the first UINT32_MAX 
// bytes of the core file. Thread structures in minidump files can only use
// 32 bit memory descriptiors, so we emit them first to ensure the memory is
// in accessible with a 32 bit offset.
```

https://github.com/llvm/llvm-project/pull/95312
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [llvm] [LLDB][Minidump] Add 64b support to LLDB's minidump file builder. (PR #95312)

2024-06-17 Thread Greg Clayton via lldb-commits


@@ -20,25 +20,96 @@
 #include "lldb/Target/RegisterContext.h"
 #include "lldb/Target/StopInfo.h"
 #include "lldb/Target/ThreadList.h"
+#include "lldb/Utility/DataBufferHeap.h"
 #include "lldb/Utility/DataExtractor.h"
 #include "lldb/Utility/LLDBLog.h"
 #include "lldb/Utility/Log.h"
+#include "lldb/Utility/RangeMap.h"
 #include "lldb/Utility/RegisterValue.h"
 
 #include "llvm/ADT/StringRef.h"
 #include "llvm/BinaryFormat/Minidump.h"
 #include "llvm/Support/ConvertUTF.h"
+#include "llvm/Support/Endian.h"
 #include "llvm/Support/Error.h"
+#include "llvm/TargetParser/Triple.h"
 
 #include "Plugins/Process/minidump/MinidumpTypes.h"
+#include "lldb/lldb-enumerations.h"
+#include "lldb/lldb-forward.h"
+#include "lldb/lldb-types.h"
 
+#include 
 #include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
 
 using namespace lldb;
 using namespace lldb_private;
 using namespace llvm::minidump;
 
-void MinidumpFileBuilder::AddDirectory(StreamType type, size_t stream_size) {
+Status MinidumpFileBuilder::AddHeaderAndCalculateDirectories() {
+  // First set the offset on the file, and on the bytes saved
+  m_saved_data_size += HEADER_SIZE;

clayborg wrote:

Should't this be:
```
m_saved_data_size = HEADER_SIZE;
```
There is no need to use `+=` right?

https://github.com/llvm/llvm-project/pull/95312
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [llvm] Add support for using foreign type units in .debug_names. (PR #87740)

2024-06-17 Thread Greg Clayton via lldb-commits

clayborg wrote:

> > But we won't want a CU index back if we have a `DW_IDX_type_unit` that is a 
> > local type unit. Makes no sense to return a CUOffset from such entries.
> 
> Can you elaborate on that? I believe it doesn't make sense to you, but I just 
> don't see the logic behind it. In particular I don't understand why it makes 
> sense to return the CU offset when the DW_IDX_compile_unit attribute is 
> explicitly specified (cases 2 and 3), but not when the compile unit is 
> referred to implicitly via the lack of the attribute on a single-cu index 
> (case 1)

When we have an entry like:
```
DW_IDX_type_unit(0)
DW_IDX_die_offset(0x32)
```
And type unit at index 0 is a local type unit, then the entry describes a type 
unit DIE in the .debug_info of the current executable. The current API we have 
is in `DWARFAcceleratorTable.h` for `DWARFDebugNames::Entry` is:
```
std::optional getCUOffset() const override;
std::optional getLocalTUOffset() const override;
std::optional getForeignTUTypeSignature() const override;
```

So if we have an entry mentioned above where the type unit lives in the local 
.debug_info section, we should get an invalid value back from a call to 
`getCUOffset()` if this is a local type unit. And we should get a valid value 
back from `getLocalTUOffset()`. But it makes no sense to return the first 
compile unit for a call to `getCUOffset()` for an entry that represents a local 
type unit because it isn't related to the local type unit. 

Lets say we do allow an entry with a local type unit to return the first CU 
from the .debug_names only because there is only one CU in the .debug_names 
table. Soon `lld` will generate a single .debug_names table with multiple CUs. 
We will get no CU offset back for an entry that contains a local type unit + 
die offset (no CU specified) when using a combined .debug_names table because 
it can't rely on there only being one CU in the list, but we will get a valid 
value back for individual .debug_names tables, which makes the API usage 
inconsistent between individual tables and combined tables.

Any foreign type units that must be associated with a skeleton compile unit, 
should have both a `DW_IDX_type_unit` and a `DW_IDX_comp_unit` to make sure we 
can make this connection between a TU and originating CU.



https://github.com/llvm/llvm-project/pull/87740
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [llvm] Add support for using foreign type units in .debug_names. (PR #87740)

2024-06-17 Thread Greg Clayton via lldb-commits

clayborg wrote:

> My previous message reflected my confusion about the usefulness about the 
> DW_IDX_cu+DW_IDX_tu combo. Let me try to start over.
> 
> The thing I don't like about this patch is the duplication between 
> `getForeignTUSkeletonCUOffset` (the new function) and `getCUOffset` (the 
> existing function). Since the duplication is motivated by undesirable 
> behavior (result) of the existing function in some cases, this got me 
> thinking if there's a way to define a single function in a way that will be 
> usable in all scenarios (and still have a consistent easy-to-understand 
> definition).
> 
> To see if that's possible, let's consider the possible cases (I'm putting 
> cases with DW_IDX_tu first, as those are the interesting ones here):
> 
> 1. A single-CU index, DW_IDX_cu not present, DW_IDX_tu present
> 2. A multi-CU index, DW_IDX_cu and DW_IDX_tu present
> 
> These two definitely are the most common (of those including type units) 
> ones, but we can also have:
> 
> 3. A single-CU index, DW_IDX_cu and DW_IDX_tu present
> 4. A multi-CU index, DW_IDX_cu not present, DW_IDX_tu present
> 
> For completeness, we can also have the cases without type units. I will 
> include only include one here, as I think the others are obvious:
> 
> 5. A single-CU index, DW_IDX_cu and DW_IDX_tu **not** present
> 
> Now that we have that, what are the possible `getCUOffset`? I can think of 
> three:
> 
> a) "return the value of DW_IDX_cu. Period." If an explicit value is not 
> present return nothing. I don't think anyone wants this, but I'm mentioning 
> it for completeness. With this definition, the function should return the cu 
> offset only in the second and third cases (`NYYNN`) 
> b) "return the DW_IDX_cu value, or the single CU from the index." Let's call 
> this the "raw" version. With this definition, I think this function should 
> return the cu offset in all cases except the fourth (that one is impossible 
> to resolve): `YYYNY` 
> c) "return the DW_IDX_cu value, only if the entry describes a DIE within that 
> CU." Let's call this the "semantic" version. I believe a function with this 
> definition should not return a CU offset only in the last case: `Y`
> 
> Now, the problem I see is that the current implementation of `getCUOffset` is 
> **neither** of these options. If an entry has an (explicit) DW_IDX_cu, it 
> will always return it (even if it also contains DW_IDX_tu). However, an 
> implicit CU will only be returned if DW_IDX_tu is not present. I.e, this 
> function does a `NYNNY`.
> 
> Therefore, my proposal is to redefine the function to do (b), which 
> essentially amounts to deleting these two lines:
> 
> ```
>   if (lookup(dwarf::DW_IDX_type_unit).has_value())
> return std::nullopt;
> ```

But we won't want a CU index back if we have a `DW_IDX_type_unit` that is a 
local type unit. Makes no sense to return a CUOffset from such entries. So 
maybe we modify this be:

```
std::optional DWARFDebugNames::Entry::getCUIndex() const {
  if (std::optional Off = lookup(dwarf::DW_IDX_compile_unit))
return Off->getAsUnsignedConstant();
  // In a per-CU index, the entries without a DW_IDX_compile_unit attribute
  // implicitly refer to the single CU, but only if we don't have a
  // DW_IDX_type_unit that is a foreign type unit.
  if (IsForeignTypeUnit())
return std::nullopt;
  if (NameIdx->getCUCount() == 1)
return 0;
  return std::nullopt;
}
```
Then we implement a `bool IsForeignTypeUnit() const` that just checks if there 
is a DW_IDX_type_unit whose index is a foreign type unit.

> 
> Besides providing a consistent definition of the function (YMMV, if you can 
> provide an explanation for the current behavior, I'd like to hear it), it 
> would also enable you to reuse it in `getForeignTUSkeletonCUOffset`, as that 
> is exactly the behavior you need there (although, at that point, I don't 
> think `getForeignTUSkeletonCUOffset` needs to exist as a separate function, 
> as it will be simple enough to inline into lldb).

That is fine with me as long as you agree with the above fix.

Let me know if the above fix to `DWARFDebugNames::Entry::getCUIndex()` makes 
sense.

https://github.com/llvm/llvm-project/pull/87740
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [llvm] [LLDB][Minidump] Add 64b support to LLDB's minidump file builder. (PR #95312)

2024-06-14 Thread Greg Clayton via lldb-commits


@@ -791,26 +812,101 @@ void MinidumpFileBuilder::AddLinuxFileStreams(
   size_t size = memory_buffer->getBufferSize();
   if (size == 0)
 continue;
-  AddDirectory(stream, size);
+  error = AddDirectory(stream, size);
+  if (error.Fail())
+return error;
   m_data.AppendData(memory_buffer->getBufferStart(), size);
 }
   }
+
+  return error;
 }
 
-Status MinidumpFileBuilder::Dump(lldb::FileUP _file) const {
-  constexpr size_t header_size = sizeof(llvm::minidump::Header);
-  constexpr size_t directory_size = sizeof(llvm::minidump::Directory);
+Status MinidumpFileBuilder::AddMemoryList(SaveCoreStyle core_style) {
+  Status error;
+
+  Process::CoreFileMemoryRanges ranges_32;
+  Process::CoreFileMemoryRanges ranges_64;
+  error = m_process_sp->CalculateCoreFileSaveRanges(
+  SaveCoreStyle::eSaveCoreStackOnly, ranges_32);
+  if (error.Fail())
+return error;
+
+  std::set stack_start_addresses;
+  for (const auto _range : ranges_32)
+stack_start_addresses.insert(core_range.range.start());
+
+  uint64_t total_size =
+  ranges_32.size() * sizeof(llvm::minidump::MemoryDescriptor);
+  for (const auto _range : ranges_32)
+total_size += core_range.range.size();

clayborg wrote:

Merge this `total_size` calculation stuff into the loop above on line 836. No 
need to iterate over this twice.

https://github.com/llvm/llvm-project/pull/95312
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [llvm] [LLDB][Minidump] Add 64b support to LLDB's minidump file builder. (PR #95312)

2024-06-14 Thread Greg Clayton via lldb-commits


@@ -858,10 +953,247 @@ Status MinidumpFileBuilder::Dump(lldb::FileUP 
_file) const {
   return error;
 }
 
-size_t MinidumpFileBuilder::GetDirectoriesNum() const {
-  return m_directories.size();
+static size_t GetLargestRange(const Process::CoreFileMemoryRanges ) {
+  size_t max_size = 0;
+  for (const auto _range : ranges) {
+max_size = std::max(max_size, core_range.range.size());
+  }
+  return max_size;
 }
 
-size_t MinidumpFileBuilder::GetCurrentDataEndOffset() const {
-  return sizeof(llvm::minidump::Header) + m_data.GetByteSize();
+Status MinidumpFileBuilder::AddMemoryList_32(
+  Process::CoreFileMemoryRanges ) {
+  std::vector descriptors;
+  Status error;
+  if (ranges.size() == 0)
+return error;
+
+  Log *log = GetLog(LLDBLog::Object);
+  size_t region_index = 0;
+  auto data_up = std::make_unique(GetLargestRange(ranges), 0);
+  for (const auto _range : ranges) {
+// Take the offset before we write.
+const size_t offset_for_data = GetCurrentDataEndOffset();
+const addr_t addr = core_range.range.start();
+const addr_t size = core_range.range.size();
+const addr_t end = core_range.range.end();
+
+LLDB_LOGF(log,
+  "AddMemoryList %zu/%zu reading memory for region "
+  "(%zu bytes) [%zx, %zx)",
+  region_index, ranges.size(), size, addr, addr + size);
+++region_index;
+
+const size_t bytes_read =
+m_process_sp->ReadMemory(addr, data_up->GetBytes(), size, error);
+if (error.Fail() || bytes_read == 0) {
+  LLDB_LOGF(log, "Failed to read memory region. Bytes read: %zu, error: 
%s",
+bytes_read, error.AsCString());
+  // Just skip sections with errors or zero bytes in 32b mode
+  continue;
+} else if (bytes_read != size) {
+  LLDB_LOGF(log, "Memory region at: %zu failed to read %zu bytes", addr,
+size);
+}
+
+MemoryDescriptor descriptor;
+descriptor.StartOfMemoryRange =
+static_cast(addr);
+descriptor.Memory.DataSize =
+static_cast(bytes_read);
+descriptor.Memory.RVA =
+static_cast(offset_for_data);

clayborg wrote:

You can just assign these values with out using the `static_cast` (and yes 
there are many places in this code doing these static_cast calls unecessarily:
```
 descriptor.StartOfMemoryRange = addr;
 descriptor.Memory.DataSize = bytes_read;
 descriptor.Memory.RVA = offset_for_data;
```

https://github.com/llvm/llvm-project/pull/95312
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [llvm] [LLDB][Minidump] Add 64b support to LLDB's minidump file builder. (PR #95312)

2024-06-14 Thread Greg Clayton via lldb-commits


@@ -858,10 +953,247 @@ Status MinidumpFileBuilder::Dump(lldb::FileUP 
_file) const {
   return error;
 }
 
-size_t MinidumpFileBuilder::GetDirectoriesNum() const {
-  return m_directories.size();
+static size_t GetLargestRange(const Process::CoreFileMemoryRanges ) {
+  size_t max_size = 0;
+  for (const auto _range : ranges) {
+max_size = std::max(max_size, core_range.range.size());
+  }
+  return max_size;
 }
 
-size_t MinidumpFileBuilder::GetCurrentDataEndOffset() const {
-  return sizeof(llvm::minidump::Header) + m_data.GetByteSize();
+Status MinidumpFileBuilder::AddMemoryList_32(
+  Process::CoreFileMemoryRanges ) {
+  std::vector descriptors;
+  Status error;
+  if (ranges.size() == 0)
+return error;
+
+  Log *log = GetLog(LLDBLog::Object);
+  size_t region_index = 0;
+  auto data_up = std::make_unique(GetLargestRange(ranges), 0);
+  for (const auto _range : ranges) {
+// Take the offset before we write.
+const size_t offset_for_data = GetCurrentDataEndOffset();
+const addr_t addr = core_range.range.start();
+const addr_t size = core_range.range.size();
+const addr_t end = core_range.range.end();
+
+LLDB_LOGF(log,
+  "AddMemoryList %zu/%zu reading memory for region "
+  "(%zu bytes) [%zx, %zx)",
+  region_index, ranges.size(), size, addr, addr + size);
+++region_index;
+
+const size_t bytes_read =
+m_process_sp->ReadMemory(addr, data_up->GetBytes(), size, error);
+if (error.Fail() || bytes_read == 0) {
+  LLDB_LOGF(log, "Failed to read memory region. Bytes read: %zu, error: 
%s",
+bytes_read, error.AsCString());
+  // Just skip sections with errors or zero bytes in 32b mode
+  continue;
+} else if (bytes_read != size) {
+  LLDB_LOGF(log, "Memory region at: %zu failed to read %zu bytes", addr,
+size);
+}
+
+MemoryDescriptor descriptor;
+descriptor.StartOfMemoryRange =
+static_cast(addr);
+descriptor.Memory.DataSize =
+static_cast(bytes_read);
+descriptor.Memory.RVA =
+static_cast(offset_for_data);
+descriptors.push_back(descriptor);
+if (m_thread_by_range_end.count(end) > 0)
+  m_thread_by_range_end[end].Stack = descriptor;
+
+// Add the data to the buffer, flush as needed.
+error = AddData(data_up->GetBytes(), bytes_read);
+if (error.Fail())
+  return error;
+  }
+
+  // Add a directory that references this list
+  // With a size of the number of ranges as a 32 bit num
+  // And then the size of all the ranges
+  error = AddDirectory(StreamType::MemoryList,
+   sizeof(llvm::support::ulittle32_t) +
+   descriptors.size() *
+   sizeof(llvm::minidump::MemoryDescriptor));
+  if (error.Fail())
+return error;
+
+  llvm::support::ulittle32_t memory_ranges_num =
+  static_cast(descriptors.size());
+  m_data.AppendData(_ranges_num, sizeof(llvm::support::ulittle32_t));
+  // For 32b we can get away with writing off the descriptors after the data.
+  // This means no cleanup loop needed.
+  m_data.AppendData(descriptors.data(),
+descriptors.size() * sizeof(MemoryDescriptor));
+
+  return error;
+}
+
+Status MinidumpFileBuilder::AddMemoryList_64(
+Process::CoreFileMemoryRanges ) {
+  Status error;
+  if (ranges.empty()) 
+return error;
+
+  error = AddDirectory(StreamType::Memory64List,
+   (sizeof(llvm::support::ulittle64_t) * 2) +
+   ranges.size() * 
sizeof(llvm::minidump::MemoryDescriptor_64));
+  if (error.Fail())
+return error;
+
+  llvm::support::ulittle64_t memory_ranges_num =
+  static_cast(ranges.size());
+  m_data.AppendData(_ranges_num, sizeof(llvm::support::ulittle64_t));
+  // Capture the starting offset for all the descriptors so we can clean them 
up
+  // if needed.
+  offset_t starting_offset = GetCurrentDataEndOffset() + 
sizeof(llvm::support::ulittle64_t);
+  // The base_rva needs to start after the directories, which is right after
+  // this 8 byte variable.
+  offset_t base_rva = starting_offset + (ranges.size() * 
sizeof(llvm::minidump::MemoryDescriptor_64));
+  llvm::support::ulittle64_t memory_ranges_base_rva =
+  static_cast(base_rva);
+  m_data.AppendData(_ranges_base_rva,
+sizeof(llvm::support::ulittle64_t));
+
+  bool cleanup_required = false;
+  std::vector descriptors;
+  // Enumerate the ranges and create the memory descriptors so we can append
+  // them first
+  for (const auto core_range : ranges) {
+// Add the space required to store the memory descriptor
+MemoryDescriptor_64 memory_desc;
+memory_desc.StartOfMemoryRange =
+static_cast(core_range.range.start());
+memory_desc.DataSize =
+static_cast(core_range.range.size());

clayborg wrote:

remove static cast

https://github.com/llvm/llvm-project/pull/95312
___

[Lldb-commits] [lldb] [llvm] [LLDB][Minidump] Add 64b support to LLDB's minidump file builder. (PR #95312)

2024-06-14 Thread Greg Clayton via lldb-commits


@@ -858,10 +953,247 @@ Status MinidumpFileBuilder::Dump(lldb::FileUP 
_file) const {
   return error;
 }
 
-size_t MinidumpFileBuilder::GetDirectoriesNum() const {
-  return m_directories.size();
+static size_t GetLargestRange(const Process::CoreFileMemoryRanges ) {
+  size_t max_size = 0;
+  for (const auto _range : ranges) {
+max_size = std::max(max_size, core_range.range.size());
+  }
+  return max_size;
 }
 
-size_t MinidumpFileBuilder::GetCurrentDataEndOffset() const {
-  return sizeof(llvm::minidump::Header) + m_data.GetByteSize();
+Status MinidumpFileBuilder::AddMemoryList_32(
+  Process::CoreFileMemoryRanges ) {
+  std::vector descriptors;
+  Status error;
+  if (ranges.size() == 0)
+return error;
+
+  Log *log = GetLog(LLDBLog::Object);
+  size_t region_index = 0;
+  auto data_up = std::make_unique(GetLargestRange(ranges), 0);
+  for (const auto _range : ranges) {
+// Take the offset before we write.
+const size_t offset_for_data = GetCurrentDataEndOffset();
+const addr_t addr = core_range.range.start();
+const addr_t size = core_range.range.size();
+const addr_t end = core_range.range.end();
+
+LLDB_LOGF(log,
+  "AddMemoryList %zu/%zu reading memory for region "
+  "(%zu bytes) [%zx, %zx)",
+  region_index, ranges.size(), size, addr, addr + size);
+++region_index;
+
+const size_t bytes_read =
+m_process_sp->ReadMemory(addr, data_up->GetBytes(), size, error);
+if (error.Fail() || bytes_read == 0) {
+  LLDB_LOGF(log, "Failed to read memory region. Bytes read: %zu, error: 
%s",
+bytes_read, error.AsCString());
+  // Just skip sections with errors or zero bytes in 32b mode
+  continue;
+} else if (bytes_read != size) {
+  LLDB_LOGF(log, "Memory region at: %zu failed to read %zu bytes", addr,
+size);
+}
+
+MemoryDescriptor descriptor;
+descriptor.StartOfMemoryRange =
+static_cast(addr);
+descriptor.Memory.DataSize =
+static_cast(bytes_read);
+descriptor.Memory.RVA =
+static_cast(offset_for_data);
+descriptors.push_back(descriptor);
+if (m_thread_by_range_end.count(end) > 0)
+  m_thread_by_range_end[end].Stack = descriptor;
+
+// Add the data to the buffer, flush as needed.
+error = AddData(data_up->GetBytes(), bytes_read);
+if (error.Fail())
+  return error;
+  }
+
+  // Add a directory that references this list
+  // With a size of the number of ranges as a 32 bit num
+  // And then the size of all the ranges
+  error = AddDirectory(StreamType::MemoryList,
+   sizeof(llvm::support::ulittle32_t) +
+   descriptors.size() *
+   sizeof(llvm::minidump::MemoryDescriptor));
+  if (error.Fail())
+return error;
+
+  llvm::support::ulittle32_t memory_ranges_num =
+  static_cast(descriptors.size());
+  m_data.AppendData(_ranges_num, sizeof(llvm::support::ulittle32_t));
+  // For 32b we can get away with writing off the descriptors after the data.
+  // This means no cleanup loop needed.
+  m_data.AppendData(descriptors.data(),
+descriptors.size() * sizeof(MemoryDescriptor));
+
+  return error;
+}
+
+Status MinidumpFileBuilder::AddMemoryList_64(
+Process::CoreFileMemoryRanges ) {
+  Status error;
+  if (ranges.empty()) 
+return error;
+
+  error = AddDirectory(StreamType::Memory64List,
+   (sizeof(llvm::support::ulittle64_t) * 2) +
+   ranges.size() * 
sizeof(llvm::minidump::MemoryDescriptor_64));
+  if (error.Fail())
+return error;
+
+  llvm::support::ulittle64_t memory_ranges_num =
+  static_cast(ranges.size());
+  m_data.AppendData(_ranges_num, sizeof(llvm::support::ulittle64_t));
+  // Capture the starting offset for all the descriptors so we can clean them 
up
+  // if needed.
+  offset_t starting_offset = GetCurrentDataEndOffset() + 
sizeof(llvm::support::ulittle64_t);
+  // The base_rva needs to start after the directories, which is right after
+  // this 8 byte variable.
+  offset_t base_rva = starting_offset + (ranges.size() * 
sizeof(llvm::minidump::MemoryDescriptor_64));
+  llvm::support::ulittle64_t memory_ranges_base_rva =
+  static_cast(base_rva);

clayborg wrote:

no static cast

https://github.com/llvm/llvm-project/pull/95312
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [llvm] [LLDB][Minidump] Add 64b support to LLDB's minidump file builder. (PR #95312)

2024-06-14 Thread Greg Clayton via lldb-commits


@@ -20,25 +20,104 @@
 #include "lldb/Target/RegisterContext.h"
 #include "lldb/Target/StopInfo.h"
 #include "lldb/Target/ThreadList.h"
+#include "lldb/Utility/DataBufferHeap.h"
 #include "lldb/Utility/DataExtractor.h"
 #include "lldb/Utility/LLDBLog.h"
 #include "lldb/Utility/Log.h"
+#include "lldb/Utility/RangeMap.h"
 #include "lldb/Utility/RegisterValue.h"
 
 #include "llvm/ADT/StringRef.h"
 #include "llvm/BinaryFormat/Minidump.h"
 #include "llvm/Support/ConvertUTF.h"
+#include "llvm/Support/Endian.h"
 #include "llvm/Support/Error.h"
+#include "llvm/TargetParser/Triple.h"
 
 #include "Plugins/Process/minidump/MinidumpTypes.h"
+#include "lldb/lldb-enumerations.h"
+#include "lldb/lldb-forward.h"
+#include "lldb/lldb-types.h"
 
+#include 
 #include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
 
 using namespace lldb;
 using namespace lldb_private;
 using namespace llvm::minidump;
 
-void MinidumpFileBuilder::AddDirectory(StreamType type, size_t stream_size) {
+Status MinidumpFileBuilder::AddHeaderAndCalculateDirectories() {
+  // First set the offset on the file, and on the bytes saved
+  m_saved_data_size += header_size;
+  // We know we will have at least Misc, SystemInfo, Modules, and ThreadList
+  // (corresponding memory list for stacks) And an additional memory list for
+  // non-stacks.
+  lldb_private::Target  = m_process_sp->GetTarget();
+  m_expected_directories = 6;
+  // Check if OS is linux and reserve directory space for all linux specific 
breakpad extension directories.
+  if (target.GetArchitecture().GetTriple().getOS() ==
+  llvm::Triple::OSType::Linux)
+m_expected_directories += 9;
+
+  // Go through all of the threads and check for exceptions.
+  lldb_private::ThreadList thread_list = m_process_sp->GetThreadList();
+  const uint32_t num_threads = thread_list.GetSize();
+  for (uint32_t thread_idx = 0; thread_idx < num_threads; ++thread_idx) {
+ThreadSP thread_sp(thread_list.GetThreadAtIndex(thread_idx));
+StopInfoSP stop_info_sp = thread_sp->GetStopInfo();
+if (stop_info_sp &&
+stop_info_sp->GetStopReason() == StopReason::eStopReasonException) {
+  m_expected_directories++;
+}
+  }
+
+  // Now offset the file by the directores so we can write them in later.
+  offset_t directory_offset = m_expected_directories * directory_size;
+  m_saved_data_size += directory_offset;
+  Status error;
+  size_t zeroes = 0; // 8 0's
+  size_t remaining_bytes = m_saved_data_size;
+  while (remaining_bytes > 0) {
+// Keep filling in zero's until we preallocate enough space for the header
+// and directory sections.
+size_t bytes_written = std::min(remaining_bytes, sizeof(size_t));
+error = m_core_file->Write(, bytes_written);
+if (error.Fail()) {
+  error.SetErrorStringWithFormat(
+"Unable to write header and directory padding (written %zd/%zd)",
+remaining_bytes - m_saved_data_size, m_saved_data_size);
+  break;
+}
+
+remaining_bytes -= bytes_written;
+  }

clayborg wrote:

Just set the file position in the `m_core_file`:
```
m_core_file->SeekFromStart(m_saved_data_size);
```
And remove this entire while loop.

https://github.com/llvm/llvm-project/pull/95312
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [llvm] [LLDB][Minidump] Add 64b support to LLDB's minidump file builder. (PR #95312)

2024-06-14 Thread Greg Clayton via lldb-commits


@@ -28,17 +29,90 @@
 #include "llvm/ADT/StringRef.h"
 #include "llvm/BinaryFormat/Minidump.h"
 #include "llvm/Support/ConvertUTF.h"
+#include "llvm/Support/Endian.h"
 #include "llvm/Support/Error.h"
+#include "llvm/TargetParser/Triple.h"
 
 #include "Plugins/Process/minidump/MinidumpTypes.h"
+#include "lldb/lldb-enumerations.h"
+#include "lldb/lldb-forward.h"
+#include "lldb/lldb-types.h"
 
+#include 
 #include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
 
 using namespace lldb;
 using namespace lldb_private;
 using namespace llvm::minidump;
 
-void MinidumpFileBuilder::AddDirectory(StreamType type, size_t stream_size) {
+Status MinidumpFileBuilder::AddHeaderAndCalculateDirectories() {
+  // First set the offset on the file, and on the bytes saved
+  m_saved_data_size += header_size;

clayborg wrote:

Is there a better name for `m_saved_data_size`? 

https://github.com/llvm/llvm-project/pull/95312
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [llvm] [LLDB][Minidump] Add 64b support to LLDB's minidump file builder. (PR #95312)

2024-06-14 Thread Greg Clayton via lldb-commits


@@ -858,10 +953,247 @@ Status MinidumpFileBuilder::Dump(lldb::FileUP 
_file) const {
   return error;
 }
 
-size_t MinidumpFileBuilder::GetDirectoriesNum() const {
-  return m_directories.size();
+static size_t GetLargestRange(const Process::CoreFileMemoryRanges ) {
+  size_t max_size = 0;
+  for (const auto _range : ranges) {
+max_size = std::max(max_size, core_range.range.size());
+  }
+  return max_size;
 }
 
-size_t MinidumpFileBuilder::GetCurrentDataEndOffset() const {
-  return sizeof(llvm::minidump::Header) + m_data.GetByteSize();
+Status MinidumpFileBuilder::AddMemoryList_32(
+  Process::CoreFileMemoryRanges ) {
+  std::vector descriptors;
+  Status error;
+  if (ranges.size() == 0)
+return error;
+
+  Log *log = GetLog(LLDBLog::Object);
+  size_t region_index = 0;
+  auto data_up = std::make_unique(GetLargestRange(ranges), 0);
+  for (const auto _range : ranges) {
+// Take the offset before we write.
+const size_t offset_for_data = GetCurrentDataEndOffset();
+const addr_t addr = core_range.range.start();
+const addr_t size = core_range.range.size();
+const addr_t end = core_range.range.end();
+
+LLDB_LOGF(log,
+  "AddMemoryList %zu/%zu reading memory for region "
+  "(%zu bytes) [%zx, %zx)",
+  region_index, ranges.size(), size, addr, addr + size);
+++region_index;
+
+const size_t bytes_read =
+m_process_sp->ReadMemory(addr, data_up->GetBytes(), size, error);
+if (error.Fail() || bytes_read == 0) {
+  LLDB_LOGF(log, "Failed to read memory region. Bytes read: %zu, error: 
%s",
+bytes_read, error.AsCString());
+  // Just skip sections with errors or zero bytes in 32b mode
+  continue;
+} else if (bytes_read != size) {
+  LLDB_LOGF(log, "Memory region at: %zu failed to read %zu bytes", addr,
+size);
+}
+
+MemoryDescriptor descriptor;
+descriptor.StartOfMemoryRange =
+static_cast(addr);
+descriptor.Memory.DataSize =
+static_cast(bytes_read);
+descriptor.Memory.RVA =
+static_cast(offset_for_data);
+descriptors.push_back(descriptor);
+if (m_thread_by_range_end.count(end) > 0)
+  m_thread_by_range_end[end].Stack = descriptor;
+
+// Add the data to the buffer, flush as needed.
+error = AddData(data_up->GetBytes(), bytes_read);
+if (error.Fail())
+  return error;
+  }
+
+  // Add a directory that references this list
+  // With a size of the number of ranges as a 32 bit num
+  // And then the size of all the ranges
+  error = AddDirectory(StreamType::MemoryList,
+   sizeof(llvm::support::ulittle32_t) +
+   descriptors.size() *
+   sizeof(llvm::minidump::MemoryDescriptor));
+  if (error.Fail())
+return error;
+
+  llvm::support::ulittle32_t memory_ranges_num =
+  static_cast(descriptors.size());

clayborg wrote:

```
llvm::support::ulittle32_t memory_ranges_num(descriptors.size());
```
No need for static_cast right. Lots of places already had these incorrect extra 
static_cast calls..

https://github.com/llvm/llvm-project/pull/95312
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [llvm] [LLDB][Minidump] Add 64b support to LLDB's minidump file builder. (PR #95312)

2024-06-14 Thread Greg Clayton via lldb-commits


@@ -797,20 +794,89 @@ void MinidumpFileBuilder::AddLinuxFileStreams(
   }
 }
 
-Status MinidumpFileBuilder::Dump(lldb::FileUP _file) const {
-  constexpr size_t header_size = sizeof(llvm::minidump::Header);
-  constexpr size_t directory_size = sizeof(llvm::minidump::Directory);
+Status MinidumpFileBuilder::AddMemory(SaveCoreStyle core_style) {
+  Status error;
+
+  Process::CoreFileMemoryRanges ranges_32;
+  Process::CoreFileMemoryRanges ranges_64;
+  error = m_process_sp->CalculateCoreFileSaveRanges(
+  SaveCoreStyle::eSaveCoreStackOnly, ranges_32);
+  if (error.Fail())
+return error;
 
+  std::set stack_start_addresses;
+  for (const auto _range : ranges_32)
+stack_start_addresses.insert(core_range.range.start());
+
+  uint64_t total_size =
+  ranges_32.size() * sizeof(llvm::minidump::MemoryDescriptor);
+  for (const auto _range : ranges_32)
+total_size += core_range.range.size();
+
+  if (total_size >= UINT32_MAX) {
+error.SetErrorStringWithFormat("Unable to write minidump. Stack memory "
+   "exceeds 32b limit. (Num Stacks %zu)",
+   ranges_32.size());
+return error;
+  }
+
+  Process::CoreFileMemoryRanges all_core_memory_ranges;
+  if (core_style != SaveCoreStyle::eSaveCoreStackOnly) {
+error = m_process_sp->CalculateCoreFileSaveRanges(core_style,
+  all_core_memory_ranges);
+if (error.Fail())
+  return error;
+  }
+
+  // We need to calculate the MemoryDescriptor size in the worst case
+  // Where all memory descriptors are 64b. We also leave some additional 
padding
+  // So that we convert over to 64b with space to spare. This does not waste
+  // space in the dump But instead converts some memory from being in the
+  // memorylist_32 to the memorylist_64.
+  total_size += 256 + (ranges_64.size() - stack_start_addresses.size()) *
+  sizeof(llvm::minidump::MemoryDescriptor_64);
+
+  for (const auto _range : all_core_memory_ranges) {
+addr_t size_to_add =
+core_range.range.size() + sizeof(llvm::minidump::MemoryDescriptor);
+if (stack_start_addresses.count(core_range.range.start()) > 0) {
+  // Don't double save stacks.
+  continue;
+} else if (total_size + size_to_add < UINT32_MAX) {
+  ranges_32.push_back(core_range);
+  total_size += core_range.range.size();
+  total_size += sizeof(llvm::minidump::MemoryDescriptor);

clayborg wrote:

This can still be just:
```
total_size += size_to_add;
```

https://github.com/llvm/llvm-project/pull/95312
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [llvm] [LLDB][Minidump] Add 64b support to LLDB's minidump file builder. (PR #95312)

2024-06-14 Thread Greg Clayton via lldb-commits


@@ -81,38 +82,42 @@ Status 
MinidumpFileBuilder::AddHeaderAndCalculateDirectories() {
   // Now offset the file by the directores so we can write them in later.
   offset_t directory_offset = m_expected_directories * directory_size;
   m_saved_data_size += directory_offset;
-  // Replace this when we make a better way to do this.
   Status error;
-  Header empty_header;
-  size_t bytes_written;
-  bytes_written = header_size;
-  error = m_core_file->Write(_header, bytes_written);
-  if (error.Fail() || bytes_written != header_size) {
-if (bytes_written != header_size)
+  size_t zeroes = 0; // 8 0's
+  size_t remaining_bytes = m_saved_data_size;
+  while (remaining_bytes > 0) {
+// Keep filling in zero's until we preallocate enough space for the header
+// and directory sections.
+size_t bytes_written = std::min(remaining_bytes, sizeof(size_t));
+error = m_core_file->Write(, bytes_written);
+if (error.Fail()) {
   error.SetErrorStringWithFormat(
-  "unable to write the header (written %zd/%zd)", bytes_written,
-  header_size);
-return error;
-  }
-
-  for (uint i = 0; i < m_expected_directories; i++) {
-size_t bytes_written;
-bytes_written = directory_size;
-Directory empty_directory;
-error = m_core_file->Write(_directory, bytes_written);
-if (error.Fail() || bytes_written != directory_size) {
-  if (bytes_written != directory_size)
-error.SetErrorStringWithFormat(
-"unable to write the directory (written %zd/%zd)", bytes_written,
-directory_size);
-  return error;
+"Unable to write header and directory padding (written %zd/%zd)",
+remaining_bytes - m_saved_data_size, m_saved_data_size);
+  break;
 }
+
+remaining_bytes -= bytes_written;
   }

clayborg wrote:

Remove this while look and complex functionality and just call:
```
m_core_file->SeekFromStart(m_saved_data_size);
```
No need to write zeroes.

https://github.com/llvm/llvm-project/pull/95312
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [llvm] [LLDB][Minidump] Add 64b support to LLDB's minidump file builder. (PR #95312)

2024-06-14 Thread Greg Clayton via lldb-commits


@@ -791,26 +812,101 @@ void MinidumpFileBuilder::AddLinuxFileStreams(
   size_t size = memory_buffer->getBufferSize();
   if (size == 0)
 continue;
-  AddDirectory(stream, size);
+  error = AddDirectory(stream, size);
+  if (error.Fail())
+return error;
   m_data.AppendData(memory_buffer->getBufferStart(), size);
 }
   }
+
+  return error;
 }
 
-Status MinidumpFileBuilder::Dump(lldb::FileUP _file) const {
-  constexpr size_t header_size = sizeof(llvm::minidump::Header);
-  constexpr size_t directory_size = sizeof(llvm::minidump::Directory);
+Status MinidumpFileBuilder::AddMemoryList(SaveCoreStyle core_style) {
+  Status error;
+
+  Process::CoreFileMemoryRanges ranges_32;
+  Process::CoreFileMemoryRanges ranges_64;
+  error = m_process_sp->CalculateCoreFileSaveRanges(
+  SaveCoreStyle::eSaveCoreStackOnly, ranges_32);
+  if (error.Fail())
+return error;
+
+  std::set stack_start_addresses;
+  for (const auto _range : ranges_32)
+stack_start_addresses.insert(core_range.range.start());
+
+  uint64_t total_size =
+  ranges_32.size() * sizeof(llvm::minidump::MemoryDescriptor);
+  for (const auto _range : ranges_32)
+total_size += core_range.range.size();
+
+  if (total_size >= UINT32_MAX) {
+error.SetErrorStringWithFormat("Unable to write minidump. Stack memory "
+   "exceeds 32b limit. (Num Stacks %zu)",
+   ranges_32.size());
+return error;
+  }
+
+  Process::CoreFileMemoryRanges all_core_memory_ranges;
+  if (core_style != SaveCoreStyle::eSaveCoreStackOnly) {
+error = m_process_sp->CalculateCoreFileSaveRanges(core_style,
+  all_core_memory_ranges);
+if (error.Fail())
+  return error;
+  }
+
+
+  // We need to calculate the MemoryDescriptor size in the worst case
+  // Where all memory descriptors are 64b. We also leave some additional 
padding
+  // So that we convert over to 64b with space to spare. This does not waste
+  // space in the dump But instead converts some memory from being in the
+  // memorylist_32 to the memorylist_64.
+  total_size += 256 + (all_core_memory_ranges.size() - 
stack_start_addresses.size()) *
+  sizeof(llvm::minidump::MemoryDescriptor_64);
 
+  for (const auto _range : all_core_memory_ranges) {
+addr_t size_to_add =
+core_range.range.size() + sizeof(llvm::minidump::MemoryDescriptor);
+if (stack_start_addresses.count(core_range.range.start()) > 0) 
+  // Don't double save stacks.
+  continue;
+
+if (total_size + size_to_add < UINT32_MAX) {
+  ranges_32.push_back(core_range);
+  total_size += core_range.range.size();
+  total_size += sizeof(llvm::minidump::MemoryDescriptor);
+} else {
+  ranges_64.push_back(core_range);
+}
+  }
+
+  error = AddMemoryList_32(ranges_32);
+  if (error.Fail())
+return error;
+
+  // Add the remaining memory as a 64b range.
+  if (ranges_64.size() > 0) {

clayborg wrote:

```
if (!ranges_64.empty()) {
```

https://github.com/llvm/llvm-project/pull/95312
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [llvm] [LLDB][Minidump] Add 64b support to LLDB's minidump file builder. (PR #95312)

2024-06-14 Thread Greg Clayton via lldb-commits


@@ -858,10 +953,247 @@ Status MinidumpFileBuilder::Dump(lldb::FileUP 
_file) const {
   return error;
 }
 
-size_t MinidumpFileBuilder::GetDirectoriesNum() const {
-  return m_directories.size();
+static size_t GetLargestRange(const Process::CoreFileMemoryRanges ) {
+  size_t max_size = 0;
+  for (const auto _range : ranges) {
+max_size = std::max(max_size, core_range.range.size());
+  }
+  return max_size;
 }
 
-size_t MinidumpFileBuilder::GetCurrentDataEndOffset() const {
-  return sizeof(llvm::minidump::Header) + m_data.GetByteSize();
+Status MinidumpFileBuilder::AddMemoryList_32(
+  Process::CoreFileMemoryRanges ) {
+  std::vector descriptors;
+  Status error;
+  if (ranges.size() == 0)
+return error;
+
+  Log *log = GetLog(LLDBLog::Object);
+  size_t region_index = 0;
+  auto data_up = std::make_unique(GetLargestRange(ranges), 0);
+  for (const auto _range : ranges) {
+// Take the offset before we write.
+const size_t offset_for_data = GetCurrentDataEndOffset();
+const addr_t addr = core_range.range.start();
+const addr_t size = core_range.range.size();
+const addr_t end = core_range.range.end();
+
+LLDB_LOGF(log,
+  "AddMemoryList %zu/%zu reading memory for region "
+  "(%zu bytes) [%zx, %zx)",
+  region_index, ranges.size(), size, addr, addr + size);
+++region_index;
+
+const size_t bytes_read =
+m_process_sp->ReadMemory(addr, data_up->GetBytes(), size, error);
+if (error.Fail() || bytes_read == 0) {
+  LLDB_LOGF(log, "Failed to read memory region. Bytes read: %zu, error: 
%s",
+bytes_read, error.AsCString());
+  // Just skip sections with errors or zero bytes in 32b mode
+  continue;
+} else if (bytes_read != size) {
+  LLDB_LOGF(log, "Memory region at: %zu failed to read %zu bytes", addr,
+size);
+}
+
+MemoryDescriptor descriptor;
+descriptor.StartOfMemoryRange =
+static_cast(addr);
+descriptor.Memory.DataSize =
+static_cast(bytes_read);
+descriptor.Memory.RVA =
+static_cast(offset_for_data);
+descriptors.push_back(descriptor);
+if (m_thread_by_range_end.count(end) > 0)
+  m_thread_by_range_end[end].Stack = descriptor;
+
+// Add the data to the buffer, flush as needed.
+error = AddData(data_up->GetBytes(), bytes_read);
+if (error.Fail())
+  return error;
+  }
+
+  // Add a directory that references this list
+  // With a size of the number of ranges as a 32 bit num
+  // And then the size of all the ranges
+  error = AddDirectory(StreamType::MemoryList,
+   sizeof(llvm::support::ulittle32_t) +
+   descriptors.size() *
+   sizeof(llvm::minidump::MemoryDescriptor));

clayborg wrote:

indent ok here? Run clang-format on this

https://github.com/llvm/llvm-project/pull/95312
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [llvm] [LLDB][Minidump] Add 64b support to LLDB's minidump file builder. (PR #95312)

2024-06-14 Thread Greg Clayton via lldb-commits


@@ -858,10 +953,247 @@ Status MinidumpFileBuilder::Dump(lldb::FileUP 
_file) const {
   return error;
 }
 
-size_t MinidumpFileBuilder::GetDirectoriesNum() const {
-  return m_directories.size();
+static size_t GetLargestRange(const Process::CoreFileMemoryRanges ) {
+  size_t max_size = 0;
+  for (const auto _range : ranges) {
+max_size = std::max(max_size, core_range.range.size());
+  }

clayborg wrote:

remove `{}` from single line for statement per llvm coding guidelines

https://github.com/llvm/llvm-project/pull/95312
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [llvm] Add support for using foreign type units in .debug_names. (PR #87740)

2024-06-14 Thread Greg Clayton via lldb-commits

clayborg wrote:

> Most of the patch is very clean, but I'm bothered by the 
> `getForeignTUSkeletonCUOffset` function, how it opens up with a mostly 
> redundant (the callers checks this already) call to 
> `getForeignTUTypeSignature`, and then proceeds with a reimplementation of 
> `getCUOffset` (sans the type unit check). I think we could design a better 
> set of APIs for this, but I'm not sure what those is, because I'm unclear of 
> the meaning of various combinations of DW_IDX unit entries.

If we have an entry with a `DW_IDX_type_unit`, it can be a normal type unit, or 
a foreign type unit, that depends on the indexes value. If it is less than the 
number of local type units, then it is a local type unit and there should be no 
`DW_IDX_comp_unit` in the entry, else it is a foreign type unit from a .dwo or 
.dwp file. If we have a .dwp file, we need the `DW_IDX_comp_unit` to be able to 
tell if the foreign type unit made it into the .dwp file, or if this is an 
entry that represents the a different type unit and we should ignore it.  If we 
have no .dwp file, then all entries for foreign type units are valid and we 
don't need to check the compile unit it came from. 

So if you just ask an entry for its `DW_IDX_comp_unit`, you will get an answer 
for an entry from a normal compile unit, or for a foreign type unit with a 
compile unit that will be used to discriminate for the .dwp file case. 

So this function is named `getForeignTUSkeletonCUOffset()` to help say "this 
might have  compile unit entry, but we only want it if this is a foreign type 
unit. I took me a while to understand the spec when it came to foreign type 
units...

> What the new function (I think) essentially does is "give me the CU 
> associated with this entry even if the entry does not describe a DIE in this 
> CU" (because `DW_IDX_die_offset` is relative to a type unit)". I think this 
> API would make sense, even without needing to talk about type units. However, 
> is it actually implementable? For single-CU indexes, that's fine, because we 
> can kind of assume all entries are related to that CU. But what about 
> multi-CU indexes? The only way to determine the CU there is to have an 
> explicit attribute. Are we saying that each entry in a multi-CU index must 
> have a DW_IDX_compile_unit (in addition to a DW_IDX_type_unit)?

Yes, but only if the `DW_IDX_type_unit` represents a foreign type unit, and we 
will only need the `DW_IDX_comp_unit` if we have a .dwp file. But since we 
don't know if the user will use a .dwp file, we always need to put the data for 
the originating compile uint in as a `DW_IDX_comp_unit`.

I would rather have had a `DW_IDX_skeleton_unit` to differentiate between a 
`DW_IDX_comp_unit` and requiring the user to know that they can't just find the 
compile unit, but they must find the non-skeleton compile unit,  before adding 
the `DW_IDX_die_offset`. But we don't have that in the spec...

> 
> If the answer is yes, then this function can be implemented, but then I think 
> the current implementation of `getCUOffset` (which I interpret as "give me 
> the CU offset **IF** this entry is relative to that CU") doesn't make sense 
> -- because it treats entries with an explicit `DW_IDX_compile_unit` different 
> from an implicit/missing `DW_IDX_compile_unit`. 

It doesn't treat them differently. if you ask an entry for its 
`DW_IDX_compile_unit` and it doesn't have one, we can fall back to grabbing a 
CU from the CU table, but only if the CU table has only 1 entry in it.

> And in this world, we assume that `DW_IDX_type_unit` takes precedence over 
> `DW_IDX_compile_unit` -- if both are present then `DW_IDX_die_offset` is 
> relative to the former. And I'm not sure if we would actually want to take up 
> space by putting both values into the index. Looking at existing producers 
> would be interesting, but I'm not sure if there are any (lld does not merge 
> type unit indexes right now, possibly for this very reason). Maybe one could 
> produce something with LTO?

LTO and bolt and soon lld will produce these single tables with multiple 
compile units. 

And we MUST have the `DW_IDX_comp_unit` for foreign type units because type 
units can generate differing content and one copy of the type unit will make it 
into the .dwp and we need to know from which .dwo file it came and only use the 
entries from the matching .dwo file because the offsets can be meaningless for 
type units with the same signature but that came from different .dwo files.

> 
> OTOH, if the answer is no, then the function isn't implementable in the 
> generic case. That doesn't mean you can't implement this feature -- which is 
> useful for guarding against ODR violations (exacerbated by llvm's 
> nonconforming type signature computation algorithm...). However, I think it 
> could be implemented in a much simpler way. For example, lldb could just 
> check if it's looking at a single-CU index, and get the CU offset that way. 
> No extra 

[Lldb-commits] [lldb] Add options to "statistics dump" to control what sections are dumped (PR #95075)

2024-06-14 Thread Greg Clayton via lldb-commits

https://github.com/clayborg requested changes to this pull request.


https://github.com/llvm/llvm-project/pull/95075
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] Add options to "statistics dump" to control what sections are dumped (PR #95075)

2024-06-14 Thread Greg Clayton via lldb-commits


@@ -133,7 +133,9 @@ struct ConstStringStats {
 struct StatisticsOptions {
   bool summary_only = false;
   bool load_all_debug_info = false;
-  bool include_transcript = false;
+  bool include_targets = true;
+  bool include_modules = true;

clayborg wrote:

Do we want to make all of the StatisticsOptions bool values 
`std::optional` values? Then we will know if the user has set them and we 
can do the reasoning. Accessors can be added to this `StatisticsOptions` class 
to do the right thing. Then instead of people directly accessing each 
`std::optional` we would have accessors. Something like:
```
class StatisticsOptions {
private: // Stop direct access to the member variables
  std::optional m_summary_only;
  std::optional m_load_all_debug_info;
  std::optional m_include_transcript;
  std::optional m_include_targets;
  std::optional m_include_modules;
public:
  // Summary only defaults to false.
  bool GetSummaryOnly() const { return m_summary_only.value_or(false); }
  void SetSummaryOnly(bool value) { m_summary_only = value; }
  // Now we can reason about what values to return depending on m_summary_only:
  bool GetIncludeTargets() const {
if (m_include_targets.has_value())
  return m_include_targets.value();
// m_include_targets has no value set, so return a value base on 
m_summary_only
return !GetSummaryOnly();
  }
```
Then this allows you to always do the right thing depending on what options 
people select.

https://github.com/llvm/llvm-project/pull/95075
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] Add options to "statistics dump" to control what sections are dumped (PR #95075)

2024-06-14 Thread Greg Clayton via lldb-commits


@@ -133,7 +133,9 @@ struct ConstStringStats {
 struct StatisticsOptions {
   bool summary_only = false;
   bool load_all_debug_info = false;
-  bool include_transcript = false;

clayborg wrote:

I would move this line that was removed back to where it was on line 136 (it is 
now 138). The diff will be smaller

https://github.com/llvm/llvm-project/pull/95075
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] Add options to "statistics dump" to control what sections are dumped (PR #95075)

2024-06-14 Thread Greg Clayton via lldb-commits


@@ -77,12 +78,33 @@ class CommandObjectStatsDump : public CommandObjectParsed {
 break;
   case 's':
 m_stats_options.summary_only = true;
+// In the "summary" mode, the following sections should be omitted by
+// default unless their corresponding options are explicitly given.
+// If such options were processed before 's', `m_seen_options` should
+// contain them, and we will skip setting them to `false` here. If such
+// options are not yet processed, we will set them to `false` here, and
+// they will be overwritten when the options are processed.
+if (m_seen_options.find((int)'r') == m_seen_options.end())
+  m_stats_options.include_targets = false;
+if (m_seen_options.find((int)'m') == m_seen_options.end())
+  m_stats_options.include_modules = false;
+if (m_seen_options.find((int)'t') == m_seen_options.end())
+  m_stats_options.include_transcript = false;
 break;

clayborg wrote:

We should put these smarts into the `StatisticsOptions` class so that we don't 
have to do this logic here _and_ this means that when people use the 
`SBStatisticsOptions` class via the API, we will do the right thing when using 
the API and it will match the behavior here.

https://github.com/llvm/llvm-project/pull/95075
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] Add options to "statistics dump" to control what sections are dumped (PR #95075)

2024-06-14 Thread Greg Clayton via lldb-commits

https://github.com/clayborg edited 
https://github.com/llvm/llvm-project/pull/95075
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] Add options to "statistics dump" to control what sections are dumped (PR #95075)

2024-06-14 Thread Greg Clayton via lldb-commits


@@ -44,6 +44,30 @@ void SBStatisticsOptions::SetSummaryOnly(bool b) {
 
 bool SBStatisticsOptions::GetSummaryOnly() { return m_opaque_up->summary_only; 
}
 
+void SBStatisticsOptions::SetIncludeTargets(bool b) {
+  m_opaque_up->include_targets = b;
+}
+
+bool SBStatisticsOptions::GetIncludeTargets() const {
+  return m_opaque_up->include_targets;
+}
+
+void SBStatisticsOptions::SetIncludeModules(bool b) {
+  m_opaque_up->include_modules = b;
+}
+
+bool SBStatisticsOptions::GetIncludeModules() const {
+  return m_opaque_up->include_modules;
+}
+
+void SBStatisticsOptions::SetIncludeTranscript(bool b) {
+  m_opaque_up->include_transcript = b;
+}
+
+bool SBStatisticsOptions::GetIncludeTranscript() const {
+  return m_opaque_up->include_transcript;
+}
+

clayborg wrote:

If we switch the internal `StatisticsOptions` over to use optionals + accessors 
as suggested above, this will accurately track when and if any settings are set 
here via the API, and do the right thing, just like the command line command.

https://github.com/llvm/llvm-project/pull/95075
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [llvm] Add support for using foreign type units in .debug_names. (PR #87740)

2024-06-13 Thread Greg Clayton via lldb-commits

clayborg wrote:

I think I have addressed all issues. Does anyone have time to review?

https://github.com/llvm/llvm-project/pull/87740
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [llvm] [LLDB][Minidump] Add 64b support to LLDB's minidump file builder. (PR #95312)

2024-06-13 Thread Greg Clayton via lldb-commits


@@ -59,39 +68,67 @@ class MinidumpFileBuilder {
   // Add ThreadList stream, containing information about all threads running
   // at the moment of core saving. Contains information about thread
   // contexts.
-  lldb_private::Status AddThreadList(const lldb::ProcessSP _sp);
-  // Add Exception streams for any threads that stopped with exceptions.
-  void AddExceptions(const lldb::ProcessSP _sp);
-  // Add MemoryList stream, containing dumps of important memory segments
-  lldb_private::Status AddMemoryList(const lldb::ProcessSP _sp,
- lldb::SaveCoreStyle core_style);
   // Add MiscInfo stream, mainly providing ProcessId
   void AddMiscInfo(const lldb::ProcessSP _sp);
   // Add informative files about a Linux process
   void AddLinuxFileStreams(const lldb::ProcessSP _sp);
+  // Add Exception streams for any threads that stopped with exceptions.
+  void AddExceptions(const lldb::ProcessSP _sp);
   // Dump the prepared data into file. In case of the failure data are
   // intact.
-  lldb_private::Status Dump(lldb::FileUP _file) const;
-  // Returns the current number of directories(streams) that have been so far
-  // created. This number of directories will be dumped when calling Dump()
-  size_t GetDirectoriesNum() const;
+  lldb_private::Status AddThreadList(const lldb::ProcessSP _sp);
+
+  lldb_private::Status AddMemory(const lldb::ProcessSP _sp,
+ lldb::SaveCoreStyle core_style);
+
+  lldb_private::Status DumpToFile();
 
 private:
+  // Add data to the end of the buffer, if the buffer exceeds the flush level,
+  // trigger a flush.
+  lldb_private::Status AddData(const void *data, size_t size);
+  // Add MemoryList stream, containing dumps of important memory segments
+  lldb_private::Status
+  AddMemoryList_64(const lldb::ProcessSP _sp,
+   const lldb_private::Process::CoreFileMemoryRanges );
+  lldb_private::Status
+  AddMemoryList_32(const lldb::ProcessSP _sp,
+   const lldb_private::Process::CoreFileMemoryRanges );
+  lldb_private::Status FixThreads();
+  lldb_private::Status FlushToDisk();
+
+  lldb_private::Status DumpHeader() const;
+  lldb_private::Status DumpDirectories() const;
+  bool CheckIf_64Bit(const size_t size);
   // Add directory of StreamType pointing to the current end of the prepared
   // file with the specified size.
-  void AddDirectory(llvm::minidump::StreamType type, size_t stream_size);
-  size_t GetCurrentDataEndOffset() const;
-
-  // Stores directories to later put them at the end of minidump file
+  void AddDirectory(llvm::minidump::StreamType type, uint64_t stream_size);
+  lldb::addr_t GetCurrentDataEndOffset() const;
+  // Stores directories to fill in later
   std::vector m_directories;
+  // When we write off the threads for the first time, we need to clean them up
+  // and give them the correct RVA once we write the stack memory list.
+  std::map m_thread_by_range_start;

clayborg wrote:

If it is an address then `lldb::addr_t` is the right choice. I must have 
confused this with another location that needed to use `lldb::offset_t` for an 
offset that was being stored as a `lldb::addr_t`

https://github.com/llvm/llvm-project/pull/95312
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


  1   2   3   4   5   6   7   8   9   10   >