[Lldb-commits] [lldb] [lldb] Add SBValue::GetValueAsAddress API (PR #90144)

2024-04-25 Thread Jason Molenda via lldb-commits

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


[Lldb-commits] [lldb] [lldb] Add SBValue::GetValueAsAddress API (PR #90144)

2024-04-25 Thread Jason Molenda via lldb-commits

https://github.com/jasonmolenda updated 
https://github.com/llvm/llvm-project/pull/90144

>From 3b66943d9c49fd5e71c2eb136b5bb3311e932bbc Mon Sep 17 00:00:00 2001
From: Jason Molenda 
Date: Thu, 25 Apr 2024 15:51:44 -0700
Subject: [PATCH 1/2] [lldb] Add SBValue::GetValueAsAddress API

I previously added this API via https://reviews.llvm.org/D142792
in 2023, along with changes to the ValueObject class to treat
pointer types as addresses, and to annotate those ValueObjects
with the original uint64_t byte sequence AND the name of the
symbol once stripped, if that points to a symbol.

I did this unconditionally for all pointer type ValueObjects, and
it caused several regressions in the Objective-C data formatters
which have a ValueObject of an object, it has the address of its
class -- but with ObjC, sometimes it is a "tagged pointer" which
is metadata, not an actual pointer.  (e.g. a small NSInteger value
is stored entirely in the tagged pointer, instead of a separate
object)  Treating these not-addresses as addresses -- clearing the
non-addressable-bits -- is invalid.

The original version of this patch we're using downstream only
does this bits clearing for pointer types that are specifically
decorated with the pointerauth typequal, but not all of those
clang changes are upstreamed to github main yet, so I tried this
simpler approach and hit the tagged pointer issue and bailed on
the whole patch.

This patch, however, is simply adding SBValue::GetValueAsAddress
so script writers who know that an SBValue has an address in
memory, can strip off any metadata.  It's an important API to have
for script writers when AArch64 ptrauth is in use, so I'm
going to put this part of the patch back on github main now until
we can get the rest of that original patch upstreamed.
---
 lldb/bindings/interface/SBValueDocstrings.i   | 20 +++
 lldb/include/lldb/API/SBValue.h   |  2 +
 lldb/source/API/SBValue.cpp   | 20 +++
 .../Makefile  |  3 +
 .../TestClearSBValueNonAddressableBits.py | 60 +++
 .../clear-sbvalue-nonaddressable-bits/main.c  | 27 +
 6 files changed, 132 insertions(+)
 create mode 100644 lldb/test/API/clear-sbvalue-nonaddressable-bits/Makefile
 create mode 100644 
lldb/test/API/clear-sbvalue-nonaddressable-bits/TestClearSBValueNonAddressableBits.py
 create mode 100644 lldb/test/API/clear-sbvalue-nonaddressable-bits/main.c

diff --git a/lldb/bindings/interface/SBValueDocstrings.i 
b/lldb/bindings/interface/SBValueDocstrings.i
index 6bab923e8b35a6..59fa807f5ec95c 100644
--- a/lldb/bindings/interface/SBValueDocstrings.i
+++ b/lldb/bindings/interface/SBValueDocstrings.i
@@ -135,6 +135,26 @@ linked list."
 %feature("docstring", "Expands nested expressions like .a->b[0].c[1]->d."
 ) lldb::SBValue::GetValueForExpressionPath;
 
+%feature("docstring", "
+  Return the value as an address.  On failure, LLDB_INVALID_ADDRESS
+  will be returned.  On architectures like AArch64, where the
+  top (unaddressable) bits can be used for authentication,
+  memory tagging, or top byte ignore,  this method will return
+  the value with those top bits cleared.
+
+  GetValueAsUnsigned returns the actual value, with the
+  authentication/Top Byte Ignore/Memory Tagging Extension bits.
+
+  Calling this on a random value which is not a pointer is
+  incorrect.  Call GetType().IsPointerType() if in doubt.
+
+  An SB API program may want to show both the literal byte value
+  and the address it refers to in memory.  These two SBValue
+  methods allow SB API writers to behave appropriately for their
+  interface."
+) lldb::SBValue::GetValueAsAddress;
+
+
 %feature("doctstring", "
 Returns the number for children.
 
diff --git a/lldb/include/lldb/API/SBValue.h b/lldb/include/lldb/API/SBValue.h
index bbcccaab51aaee..6fac0961910540 100644
--- a/lldb/include/lldb/API/SBValue.h
+++ b/lldb/include/lldb/API/SBValue.h
@@ -68,6 +68,8 @@ class LLDB_API SBValue {
 
   uint64_t GetValueAsUnsigned(uint64_t fail_value = 0);
 
+  lldb::addr_t GetValueAsAddress();
+
   ValueType GetValueType();
 
   // If you call this on a newly created ValueObject, it will always return
diff --git a/lldb/source/API/SBValue.cpp b/lldb/source/API/SBValue.cpp
index 94a8f3ea319e89..c8b664c86ec2d9 100644
--- a/lldb/source/API/SBValue.cpp
+++ b/lldb/source/API/SBValue.cpp
@@ -909,6 +909,26 @@ uint64_t SBValue::GetValueAsUnsigned(uint64_t fail_value) {
   return fail_value;
 }
 
+lldb::addr_t SBValue::GetValueAsAddress() {
+  addr_t fail_value = LLDB_INVALID_ADDRESS;
+  ValueLocker locker;
+  lldb::ValueObjectSP value_sp(GetSP(locker));
+  if (value_sp) {
+bool success = true;
+uint64_t ret_val = fail_value;
+ret_val = value_sp->GetValueAsUnsigned(fail_value, );
+if (!success) {
+  return fail_value;
+}
+ProcessSP process_sp = m_opaque_sp->GetProcessSP();
+if (!process_sp)
+  return ret_val;
+   

[Lldb-commits] [lldb] [lldb] Add SBValue::GetValueAsAddress API (PR #90144)

2024-04-25 Thread Jonas Devlieghere via lldb-commits

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


[Lldb-commits] [lldb] [lldb] Add SBValue::GetValueAsAddress API (PR #90144)

2024-04-25 Thread Jonas Devlieghere via lldb-commits

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

LGTM with the formatting and braces fixed.

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


[Lldb-commits] [lldb] [lldb] Add SBValue::GetValueAsAddress API (PR #90144)

2024-04-25 Thread Jonas Devlieghere via lldb-commits


@@ -909,6 +909,26 @@ uint64_t SBValue::GetValueAsUnsigned(uint64_t fail_value) {
   return fail_value;
 }
 
+lldb::addr_t SBValue::GetValueAsAddress() {
+  addr_t fail_value = LLDB_INVALID_ADDRESS;
+  ValueLocker locker;
+  lldb::ValueObjectSP value_sp(GetSP(locker));
+  if (value_sp) {
+bool success = true;
+uint64_t ret_val = fail_value;
+ret_val = value_sp->GetValueAsUnsigned(fail_value, );
+if (!success) {
+  return fail_value;
+}

JDevlieghere wrote:

No braces

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


[Lldb-commits] [lldb] [lldb] Add SBValue::GetValueAsAddress API (PR #90144)

2024-04-25 Thread via lldb-commits

github-actions[bot] wrote:




:warning: Python code formatter, darker found issues in your code. :warning:



You can test this locally with the following command:


``bash
darker --check --diff -r 
5ac744d72ad2a8d04e0ae869c4e30558dd8058e3...3b66943d9c49fd5e71c2eb136b5bb3311e932bbc
 
lldb/test/API/clear-sbvalue-nonaddressable-bits/TestClearSBValueNonAddressableBits.py
``





View the diff from darker here.


``diff
--- TestClearSBValueNonAddressableBits.py   2024-04-25 22:59:00.00 +
+++ TestClearSBValueNonAddressableBits.py   2024-04-25 23:02:15.672739 +
@@ -5,11 +5,10 @@
 from lldbsuite.test.lldbtest import *
 from lldbsuite.test import lldbutil
 
 
 class TestClearSBValueNonAddressableBits(TestBase):
-
 NO_DEBUG_INFO_TESTCASE = True
 
 # On AArch64 systems, the top bits that are not used for
 # addressing may be used for TBI, MTE, and/or pointer
 # authentication.

``




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


[Lldb-commits] [lldb] [lldb] Add SBValue::GetValueAsAddress API (PR #90144)

2024-04-25 Thread via lldb-commits

llvmbot wrote:




@llvm/pr-subscribers-lldb

Author: Jason Molenda (jasonmolenda)


Changes

I previously added this API via https://reviews.llvm.org/D142792 in 2023, along 
with changes to the ValueObject class to treat pointer types as addresses, and 
to annotate those ValueObjects with the original uint64_t byte sequence AND the 
name of the symbol once stripped, if that points to a symbol.

I did this unconditionally for all pointer type ValueObjects, and it caused 
several regressions in the Objective-C data formatters which have a ValueObject 
of an object, it has the address of its class -- but with ObjC, sometimes it is 
a "tagged pointer" which is metadata, not an actual pointer.  (e.g. a small 
NSInteger value is stored entirely in the tagged pointer, instead of a separate 
object)  Treating these not-addresses as addresses -- clearing the 
non-addressable-bits -- is invalid.

The original version of this patch we're using downstream only does this bits 
clearing for pointer types that are specifically decorated with the pointerauth 
typequal, but not all of those clang changes are upstreamed to github main yet, 
so I tried this simpler approach and hit the tagged pointer issue and bailed on 
the whole patch.

This patch, however, is simply adding SBValue::GetValueAsAddress so script 
writers who know that an SBValue has an address in memory, can strip off any 
metadata.  It's an important API to have for script writers when AArch64 
ptrauth is in use, so I'm going to put this part of the patch back on github 
main now until we can get the rest of that original patch upstreamed.

---
Full diff: https://github.com/llvm/llvm-project/pull/90144.diff


6 Files Affected:

- (modified) lldb/bindings/interface/SBValueDocstrings.i (+20) 
- (modified) lldb/include/lldb/API/SBValue.h (+2) 
- (modified) lldb/source/API/SBValue.cpp (+20) 
- (added) lldb/test/API/clear-sbvalue-nonaddressable-bits/Makefile (+3) 
- (added) 
lldb/test/API/clear-sbvalue-nonaddressable-bits/TestClearSBValueNonAddressableBits.py
 (+60) 
- (added) lldb/test/API/clear-sbvalue-nonaddressable-bits/main.c (+27) 


``diff
diff --git a/lldb/bindings/interface/SBValueDocstrings.i 
b/lldb/bindings/interface/SBValueDocstrings.i
index 6bab923e8b35a6..59fa807f5ec95c 100644
--- a/lldb/bindings/interface/SBValueDocstrings.i
+++ b/lldb/bindings/interface/SBValueDocstrings.i
@@ -135,6 +135,26 @@ linked list."
 %feature("docstring", "Expands nested expressions like .a->b[0].c[1]->d."
 ) lldb::SBValue::GetValueForExpressionPath;
 
+%feature("docstring", "
+  Return the value as an address.  On failure, LLDB_INVALID_ADDRESS
+  will be returned.  On architectures like AArch64, where the
+  top (unaddressable) bits can be used for authentication,
+  memory tagging, or top byte ignore,  this method will return
+  the value with those top bits cleared.
+
+  GetValueAsUnsigned returns the actual value, with the
+  authentication/Top Byte Ignore/Memory Tagging Extension bits.
+
+  Calling this on a random value which is not a pointer is
+  incorrect.  Call GetType().IsPointerType() if in doubt.
+
+  An SB API program may want to show both the literal byte value
+  and the address it refers to in memory.  These two SBValue
+  methods allow SB API writers to behave appropriately for their
+  interface."
+) lldb::SBValue::GetValueAsAddress;
+
+
 %feature("doctstring", "
 Returns the number for children.
 
diff --git a/lldb/include/lldb/API/SBValue.h b/lldb/include/lldb/API/SBValue.h
index bbcccaab51aaee..6fac0961910540 100644
--- a/lldb/include/lldb/API/SBValue.h
+++ b/lldb/include/lldb/API/SBValue.h
@@ -68,6 +68,8 @@ class LLDB_API SBValue {
 
   uint64_t GetValueAsUnsigned(uint64_t fail_value = 0);
 
+  lldb::addr_t GetValueAsAddress();
+
   ValueType GetValueType();
 
   // If you call this on a newly created ValueObject, it will always return
diff --git a/lldb/source/API/SBValue.cpp b/lldb/source/API/SBValue.cpp
index 94a8f3ea319e89..c8b664c86ec2d9 100644
--- a/lldb/source/API/SBValue.cpp
+++ b/lldb/source/API/SBValue.cpp
@@ -909,6 +909,26 @@ uint64_t SBValue::GetValueAsUnsigned(uint64_t fail_value) {
   return fail_value;
 }
 
+lldb::addr_t SBValue::GetValueAsAddress() {
+  addr_t fail_value = LLDB_INVALID_ADDRESS;
+  ValueLocker locker;
+  lldb::ValueObjectSP value_sp(GetSP(locker));
+  if (value_sp) {
+bool success = true;
+uint64_t ret_val = fail_value;
+ret_val = value_sp->GetValueAsUnsigned(fail_value, );
+if (!success) {
+  return fail_value;
+}
+ProcessSP process_sp = m_opaque_sp->GetProcessSP();
+if (!process_sp)
+  return ret_val;
+return process_sp->FixDataAddress(ret_val);
+  }
+
+  return fail_value;
+}
+
 bool SBValue::MightHaveChildren() {
   LLDB_INSTRUMENT_VA(this);
 
diff --git a/lldb/test/API/clear-sbvalue-nonaddressable-bits/Makefile 
b/lldb/test/API/clear-sbvalue-nonaddressable-bits/Makefile
new file mode 100644
index 

[Lldb-commits] [lldb] [lldb] Add SBValue::GetValueAsAddress API (PR #90144)

2024-04-25 Thread Jason Molenda via lldb-commits

https://github.com/jasonmolenda created 
https://github.com/llvm/llvm-project/pull/90144

I previously added this API via https://reviews.llvm.org/D142792 in 2023, along 
with changes to the ValueObject class to treat pointer types as addresses, and 
to annotate those ValueObjects with the original uint64_t byte sequence AND the 
name of the symbol once stripped, if that points to a symbol.

I did this unconditionally for all pointer type ValueObjects, and it caused 
several regressions in the Objective-C data formatters which have a ValueObject 
of an object, it has the address of its class -- but with ObjC, sometimes it is 
a "tagged pointer" which is metadata, not an actual pointer.  (e.g. a small 
NSInteger value is stored entirely in the tagged pointer, instead of a separate 
object)  Treating these not-addresses as addresses -- clearing the 
non-addressable-bits -- is invalid.

The original version of this patch we're using downstream only does this bits 
clearing for pointer types that are specifically decorated with the pointerauth 
typequal, but not all of those clang changes are upstreamed to github main yet, 
so I tried this simpler approach and hit the tagged pointer issue and bailed on 
the whole patch.

This patch, however, is simply adding SBValue::GetValueAsAddress so script 
writers who know that an SBValue has an address in memory, can strip off any 
metadata.  It's an important API to have for script writers when AArch64 
ptrauth is in use, so I'm going to put this part of the patch back on github 
main now until we can get the rest of that original patch upstreamed.

>From 3b66943d9c49fd5e71c2eb136b5bb3311e932bbc Mon Sep 17 00:00:00 2001
From: Jason Molenda 
Date: Thu, 25 Apr 2024 15:51:44 -0700
Subject: [PATCH] [lldb] Add SBValue::GetValueAsAddress API

I previously added this API via https://reviews.llvm.org/D142792
in 2023, along with changes to the ValueObject class to treat
pointer types as addresses, and to annotate those ValueObjects
with the original uint64_t byte sequence AND the name of the
symbol once stripped, if that points to a symbol.

I did this unconditionally for all pointer type ValueObjects, and
it caused several regressions in the Objective-C data formatters
which have a ValueObject of an object, it has the address of its
class -- but with ObjC, sometimes it is a "tagged pointer" which
is metadata, not an actual pointer.  (e.g. a small NSInteger value
is stored entirely in the tagged pointer, instead of a separate
object)  Treating these not-addresses as addresses -- clearing the
non-addressable-bits -- is invalid.

The original version of this patch we're using downstream only
does this bits clearing for pointer types that are specifically
decorated with the pointerauth typequal, but not all of those
clang changes are upstreamed to github main yet, so I tried this
simpler approach and hit the tagged pointer issue and bailed on
the whole patch.

This patch, however, is simply adding SBValue::GetValueAsAddress
so script writers who know that an SBValue has an address in
memory, can strip off any metadata.  It's an important API to have
for script writers when AArch64 ptrauth is in use, so I'm
going to put this part of the patch back on github main now until
we can get the rest of that original patch upstreamed.
---
 lldb/bindings/interface/SBValueDocstrings.i   | 20 +++
 lldb/include/lldb/API/SBValue.h   |  2 +
 lldb/source/API/SBValue.cpp   | 20 +++
 .../Makefile  |  3 +
 .../TestClearSBValueNonAddressableBits.py | 60 +++
 .../clear-sbvalue-nonaddressable-bits/main.c  | 27 +
 6 files changed, 132 insertions(+)
 create mode 100644 lldb/test/API/clear-sbvalue-nonaddressable-bits/Makefile
 create mode 100644 
lldb/test/API/clear-sbvalue-nonaddressable-bits/TestClearSBValueNonAddressableBits.py
 create mode 100644 lldb/test/API/clear-sbvalue-nonaddressable-bits/main.c

diff --git a/lldb/bindings/interface/SBValueDocstrings.i 
b/lldb/bindings/interface/SBValueDocstrings.i
index 6bab923e8b35a6..59fa807f5ec95c 100644
--- a/lldb/bindings/interface/SBValueDocstrings.i
+++ b/lldb/bindings/interface/SBValueDocstrings.i
@@ -135,6 +135,26 @@ linked list."
 %feature("docstring", "Expands nested expressions like .a->b[0].c[1]->d."
 ) lldb::SBValue::GetValueForExpressionPath;
 
+%feature("docstring", "
+  Return the value as an address.  On failure, LLDB_INVALID_ADDRESS
+  will be returned.  On architectures like AArch64, where the
+  top (unaddressable) bits can be used for authentication,
+  memory tagging, or top byte ignore,  this method will return
+  the value with those top bits cleared.
+
+  GetValueAsUnsigned returns the actual value, with the
+  authentication/Top Byte Ignore/Memory Tagging Extension bits.
+
+  Calling this on a random value which is not a pointer is
+  incorrect.  Call GetType().IsPointerType() if in doubt.
+
+  An SB