[Lldb-commits] [lldb] ec8df0c - [LLDB] Skip TestTlsGlobals.py for Linux Arm/AArch64

2023-09-28 Thread Muhammad Omair Javaid via lldb-commits

Author: Muhammad Omair Javaid
Date: 2023-09-28T16:16:41+05:00
New Revision: ec8df0c7e3a3d9e6352a3d8c5c4540a9d0352ca0

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

LOG: [LLDB] Skip TestTlsGlobals.py for Linux Arm/AArch64

Recently added TLS linux support fails on Arm/AArch64. I am skiping test
for now and will investigate the issue later.

Added: 


Modified: 
lldb/test/API/lang/c/tls_globals/TestTlsGlobals.py

Removed: 




diff  --git a/lldb/test/API/lang/c/tls_globals/TestTlsGlobals.py 
b/lldb/test/API/lang/c/tls_globals/TestTlsGlobals.py
index a853b284c2cce4d..dfe29b451df0a66 100644
--- a/lldb/test/API/lang/c/tls_globals/TestTlsGlobals.py
+++ b/lldb/test/API/lang/c/tls_globals/TestTlsGlobals.py
@@ -38,6 +38,7 @@ def setUp(self):
 # TLS works 
diff erently on Windows, this would need to be implemented
 # separately.
 @skipIfWindows
+@skipIf(oslist=["linux"], archs=["arm", "aarch64"])
 @skipIf(oslist=no_match([lldbplatformutil.getDarwinOSTriples(), "linux"]))
 def test(self):
 """Test thread-local storage."""



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


[Lldb-commits] [lldb] [lldb] add stop-at-user-entry option to process launch (PR #67019)

2023-09-28 Thread José Lira Junior via lldb-commits

junior-jl wrote:

I understand, thank you, Jim.

Is there anything else I should change in this PR?

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


[Lldb-commits] [lldb] Support target names with dots in more utilities (PR #65812)

2023-09-28 Thread via lldb-commits

https://github.com/dankm updated https://github.com/llvm/llvm-project/pull/65812

>From 5f5e57a5c01088e7f0b9276ed02dd436a3f9cc0a Mon Sep 17 00:00:00 2001
From: Dan McGregor 
Date: Mon, 14 Aug 2023 18:44:08 -0600
Subject: [PATCH 1/3] Support: hoist lld's executable name code to Path

Instead of using custom code to find the program name throughout
the codebase, write one function as a path helper to consistently
determine the program name. This globally correctly finds target
names with dots in them (ie freebsd13.2).
---
 lld/COFF/Driver.cpp|  2 +-
 lld/Common/Args.cpp|  6 --
 lld/ELF/Driver.cpp |  2 +-
 lld/MachO/Driver.cpp   |  2 +-
 lld/include/lld/Common/Args.h  |  2 --
 lld/wasm/Driver.cpp|  2 +-
 lldb/tools/driver/Driver.cpp   |  2 +-
 llvm/include/llvm/Support/Path.h   | 15 +++
 llvm/lib/Support/Path.cpp  |  7 +++
 llvm/tools/llvm-ar/llvm-ar.cpp |  3 ++-
 llvm/tools/llvm-cov/llvm-cov.cpp   |  2 +-
 llvm/tools/llvm-driver/llvm-driver.cpp |  2 +-
 llvm/tools/llvm-objcopy/llvm-objcopy.cpp   |  2 +-
 llvm/tools/llvm-objdump/llvm-objdump.cpp   |  2 +-
 llvm/tools/llvm-rc/llvm-rc.cpp |  2 +-
 llvm/tools/llvm-readobj/llvm-readobj.cpp   |  2 +-
 llvm/tools/llvm-symbolizer/llvm-symbolizer.cpp |  2 +-
 17 files changed, 36 insertions(+), 21 deletions(-)

diff --git a/lld/COFF/Driver.cpp b/lld/COFF/Driver.cpp
index d7476e91e03e384..03a63bf3a306b4d 100644
--- a/lld/COFF/Driver.cpp
+++ b/lld/COFF/Driver.cpp
@@ -68,7 +68,7 @@ bool link(ArrayRef args, llvm::raw_ostream 
&stdoutOS,
   auto *ctx = new COFFLinkerContext;
 
   ctx->e.initialize(stdoutOS, stderrOS, exitEarly, disableOutput);
-  ctx->e.logName = args::getFilenameWithoutExe(args[0]);
+  ctx->e.logName = sys::path::program_name(args[0]);
   ctx->e.errorLimitExceededMsg = "too many errors emitted, stopping now"
  " (use /errorlimit:0 to see all errors)";
 
diff --git a/lld/Common/Args.cpp b/lld/Common/Args.cpp
index 48c934df3a2c931..b02d023fe19aeb5 100644
--- a/lld/Common/Args.cpp
+++ b/lld/Common/Args.cpp
@@ -85,9 +85,3 @@ std::vector lld::args::getLines(MemoryBufferRef 
mb) {
   }
   return ret;
 }
-
-StringRef lld::args::getFilenameWithoutExe(StringRef path) {
-  if (path.ends_with_insensitive(".exe"))
-return sys::path::stem(path);
-  return sys::path::filename(path);
-}
diff --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp
index 9d167293574fa64..957d0da1589caf8 100644
--- a/lld/ELF/Driver.cpp
+++ b/lld/ELF/Driver.cpp
@@ -143,7 +143,7 @@ bool link(ArrayRef args, llvm::raw_ostream 
&stdoutOS,
 
 SharedFile::vernauxNum = 0;
   };
-  ctx->e.logName = args::getFilenameWithoutExe(args[0]);
+  ctx->e.logName = sys::path::program_name(args[0]);
   ctx->e.errorLimitExceededMsg = "too many errors emitted, stopping now (use "
  "--error-limit=0 to see all errors)";
 
diff --git a/lld/MachO/Driver.cpp b/lld/MachO/Driver.cpp
index 00ff3439a043be9..ed0b66d4b2ec6ba 100644
--- a/lld/MachO/Driver.cpp
+++ b/lld/MachO/Driver.cpp
@@ -1428,7 +1428,7 @@ bool link(ArrayRef argsArr, 
llvm::raw_ostream &stdoutOS,
 InputFile::resetIdCount();
   };
 
-  ctx->e.logName = args::getFilenameWithoutExe(argsArr[0]);
+  ctx->e.logName = sys::path::program_name(argsArr[0]);
 
   MachOOptTable parser;
   InputArgList args = parser.parse(argsArr.slice(1));
diff --git a/lld/include/lld/Common/Args.h b/lld/include/lld/Common/Args.h
index 60f83fbbbf1a3c9..8822707a6a1f212 100644
--- a/lld/include/lld/Common/Args.h
+++ b/lld/include/lld/Common/Args.h
@@ -38,8 +38,6 @@ uint64_t getZOptionValue(llvm::opt::InputArgList &args, int 
id, StringRef key,
 
 std::vector getLines(MemoryBufferRef mb);
 
-StringRef getFilenameWithoutExe(StringRef path);
-
 } // namespace args
 } // namespace lld
 
diff --git a/lld/wasm/Driver.cpp b/lld/wasm/Driver.cpp
index c2f5f0185781f36..f13aa520f35b100 100644
--- a/lld/wasm/Driver.cpp
+++ b/lld/wasm/Driver.cpp
@@ -89,7 +89,7 @@ bool link(ArrayRef args, llvm::raw_ostream 
&stdoutOS,
   auto *ctx = new CommonLinkerContext;
 
   ctx->e.initialize(stdoutOS, stderrOS, exitEarly, disableOutput);
-  ctx->e.logName = args::getFilenameWithoutExe(args[0]);
+  ctx->e.logName = sys::path::program_name(args[0]);
   ctx->e.errorLimitExceededMsg = "too many errors emitted, stopping now (use "
  "-error-limit=0 to see all errors)";
 
diff --git a/lldb/tools/driver/Driver.cpp b/lldb/tools/driver/Driver.cpp
index f8058f868d53ffe..2fb760ca97a001d 100644
--- a/lldb/tools/driver/Driver.cpp
+++ b/lldb/tools/driver/Driver.cpp
@@ -754,7 +754,7 @@ int main(int argc, char const *argv[]) {
   ArrayRef arg_arr = ArrayRef(argv + 1, argc - 1);
   opt::InputArgList input_args =
   T.ParseArgs(arg_arr, MissingA

[Lldb-commits] [lldb] Support target names with dots in more utilities (PR #65812)

2023-09-28 Thread via lldb-commits

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


[Lldb-commits] [lldb] [lldb] Add windows support for LLDB_EXPORT_ALL_SYMBOLS (PR #67628)

2023-09-28 Thread River Riddle via lldb-commits

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


[Lldb-commits] [lldb] [lldb] Add windows support for LLDB_EXPORT_ALL_SYMBOLS (PR #67628)

2023-09-28 Thread River Riddle via lldb-commits

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


[Lldb-commits] [lldb] [lldb] Add windows support for LLDB_EXPORT_ALL_SYMBOLS (PR #67628)

2023-09-28 Thread River Riddle via lldb-commits

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


[Lldb-commits] [lldb] Support target names with dots in more utilities (PR #65812)

2023-09-28 Thread via lldb-commits

https://github.com/dankm updated https://github.com/llvm/llvm-project/pull/65812

>From 5f5e57a5c01088e7f0b9276ed02dd436a3f9cc0a Mon Sep 17 00:00:00 2001
From: Dan McGregor 
Date: Mon, 14 Aug 2023 18:44:08 -0600
Subject: [PATCH 1/4] Support: hoist lld's executable name code to Path

Instead of using custom code to find the program name throughout
the codebase, write one function as a path helper to consistently
determine the program name. This globally correctly finds target
names with dots in them (ie freebsd13.2).
---
 lld/COFF/Driver.cpp|  2 +-
 lld/Common/Args.cpp|  6 --
 lld/ELF/Driver.cpp |  2 +-
 lld/MachO/Driver.cpp   |  2 +-
 lld/include/lld/Common/Args.h  |  2 --
 lld/wasm/Driver.cpp|  2 +-
 lldb/tools/driver/Driver.cpp   |  2 +-
 llvm/include/llvm/Support/Path.h   | 15 +++
 llvm/lib/Support/Path.cpp  |  7 +++
 llvm/tools/llvm-ar/llvm-ar.cpp |  3 ++-
 llvm/tools/llvm-cov/llvm-cov.cpp   |  2 +-
 llvm/tools/llvm-driver/llvm-driver.cpp |  2 +-
 llvm/tools/llvm-objcopy/llvm-objcopy.cpp   |  2 +-
 llvm/tools/llvm-objdump/llvm-objdump.cpp   |  2 +-
 llvm/tools/llvm-rc/llvm-rc.cpp |  2 +-
 llvm/tools/llvm-readobj/llvm-readobj.cpp   |  2 +-
 llvm/tools/llvm-symbolizer/llvm-symbolizer.cpp |  2 +-
 17 files changed, 36 insertions(+), 21 deletions(-)

diff --git a/lld/COFF/Driver.cpp b/lld/COFF/Driver.cpp
index d7476e91e03e384..03a63bf3a306b4d 100644
--- a/lld/COFF/Driver.cpp
+++ b/lld/COFF/Driver.cpp
@@ -68,7 +68,7 @@ bool link(ArrayRef args, llvm::raw_ostream 
&stdoutOS,
   auto *ctx = new COFFLinkerContext;
 
   ctx->e.initialize(stdoutOS, stderrOS, exitEarly, disableOutput);
-  ctx->e.logName = args::getFilenameWithoutExe(args[0]);
+  ctx->e.logName = sys::path::program_name(args[0]);
   ctx->e.errorLimitExceededMsg = "too many errors emitted, stopping now"
  " (use /errorlimit:0 to see all errors)";
 
diff --git a/lld/Common/Args.cpp b/lld/Common/Args.cpp
index 48c934df3a2c931..b02d023fe19aeb5 100644
--- a/lld/Common/Args.cpp
+++ b/lld/Common/Args.cpp
@@ -85,9 +85,3 @@ std::vector lld::args::getLines(MemoryBufferRef 
mb) {
   }
   return ret;
 }
-
-StringRef lld::args::getFilenameWithoutExe(StringRef path) {
-  if (path.ends_with_insensitive(".exe"))
-return sys::path::stem(path);
-  return sys::path::filename(path);
-}
diff --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp
index 9d167293574fa64..957d0da1589caf8 100644
--- a/lld/ELF/Driver.cpp
+++ b/lld/ELF/Driver.cpp
@@ -143,7 +143,7 @@ bool link(ArrayRef args, llvm::raw_ostream 
&stdoutOS,
 
 SharedFile::vernauxNum = 0;
   };
-  ctx->e.logName = args::getFilenameWithoutExe(args[0]);
+  ctx->e.logName = sys::path::program_name(args[0]);
   ctx->e.errorLimitExceededMsg = "too many errors emitted, stopping now (use "
  "--error-limit=0 to see all errors)";
 
diff --git a/lld/MachO/Driver.cpp b/lld/MachO/Driver.cpp
index 00ff3439a043be9..ed0b66d4b2ec6ba 100644
--- a/lld/MachO/Driver.cpp
+++ b/lld/MachO/Driver.cpp
@@ -1428,7 +1428,7 @@ bool link(ArrayRef argsArr, 
llvm::raw_ostream &stdoutOS,
 InputFile::resetIdCount();
   };
 
-  ctx->e.logName = args::getFilenameWithoutExe(argsArr[0]);
+  ctx->e.logName = sys::path::program_name(argsArr[0]);
 
   MachOOptTable parser;
   InputArgList args = parser.parse(argsArr.slice(1));
diff --git a/lld/include/lld/Common/Args.h b/lld/include/lld/Common/Args.h
index 60f83fbbbf1a3c9..8822707a6a1f212 100644
--- a/lld/include/lld/Common/Args.h
+++ b/lld/include/lld/Common/Args.h
@@ -38,8 +38,6 @@ uint64_t getZOptionValue(llvm::opt::InputArgList &args, int 
id, StringRef key,
 
 std::vector getLines(MemoryBufferRef mb);
 
-StringRef getFilenameWithoutExe(StringRef path);
-
 } // namespace args
 } // namespace lld
 
diff --git a/lld/wasm/Driver.cpp b/lld/wasm/Driver.cpp
index c2f5f0185781f36..f13aa520f35b100 100644
--- a/lld/wasm/Driver.cpp
+++ b/lld/wasm/Driver.cpp
@@ -89,7 +89,7 @@ bool link(ArrayRef args, llvm::raw_ostream 
&stdoutOS,
   auto *ctx = new CommonLinkerContext;
 
   ctx->e.initialize(stdoutOS, stderrOS, exitEarly, disableOutput);
-  ctx->e.logName = args::getFilenameWithoutExe(args[0]);
+  ctx->e.logName = sys::path::program_name(args[0]);
   ctx->e.errorLimitExceededMsg = "too many errors emitted, stopping now (use "
  "-error-limit=0 to see all errors)";
 
diff --git a/lldb/tools/driver/Driver.cpp b/lldb/tools/driver/Driver.cpp
index f8058f868d53ffe..2fb760ca97a001d 100644
--- a/lldb/tools/driver/Driver.cpp
+++ b/lldb/tools/driver/Driver.cpp
@@ -754,7 +754,7 @@ int main(int argc, char const *argv[]) {
   ArrayRef arg_arr = ArrayRef(argv + 1, argc - 1);
   opt::InputArgList input_args =
   T.ParseArgs(arg_arr, MissingA

[Lldb-commits] [lldb] [lldb] Add windows support for LLDB_EXPORT_ALL_SYMBOLS (PR #67628)

2023-09-28 Thread River Riddle via lldb-commits


@@ -0,0 +1,100 @@
+"""A tool for extracting a list of private lldb symbols to export for MSVC.
+
+When exporting symbols from a dll or exe we either need to mark the symbols in
+the source code as __declspec(dllexport) or supply a list of symbols to the
+linker. Private symbols in LLDB don't explicitly specific dllexport, so we
+automate that by examining the symbol table.
+"""
+
+import argparse
+import os
+import re
+import subprocess
+import sys
+
+
+def extract_symbols(nm_path: str, lib: str):
+"""Extract all of the private lldb symbols from the given path to llvm-nm 
and
+library to extract from."""
+
+# Matches mangled symbols containing 'lldb_private'.
+lldb_sym_re = r"0* [BT] (?P[?]+[^?].*lldb_private.*)"
+
+# '-g' means we only get global symbols.
+# '-p' do not waste time sorting the symbols.
+process = subprocess.Popen(
+[nm_path, "-g", "-p", lib],
+bufsize=1,
+stdout=subprocess.PIPE,
+stdin=subprocess.PIPE,
+universal_newlines=True,
+)
+process.stdin.close()
+
+lldb_symbols = set()
+for line in process.stdout:
+match = re.match(lldb_sym_re, line)
+if match:
+symbol = match.group("symbol")
+assert symbol.count(" ") == 0, (
+"Regex matched too much, probably got undecorated name as well"
+)
+# Deleting destructors start with ?_G or ?_E and can be discarded
+# because link.exe gives you a warning telling you they can't be
+# exported if you don't.
+if symbol.startswith("??_G") or symbol.startswith("??_E"):
+continue
+lldb_symbols.add(symbol)
+
+return lldb_symbols
+
+
+def main():
+parser = argparse.ArgumentParser(description="Generate LLDB dll exports")
+parser.add_argument(
+"-o", metavar="file", type=str, help="The name of the resultant export 
file."
+)
+parser.add_argument("--nm", help="Path to the llvm-nm executable.")
+parser.add_argument(
+"libs",
+metavar="lib",
+type=str,
+nargs="+",
+help="The libraries to extract symbols from.",
+)
+args = parser.parse_args()
+
+# Get the list of libraries to extract symbols from
+libs = list()
+for lib in args.libs:
+# When invoked by cmake the arguments are the cmake target names of the
+# libraries, so we need to add .lib/.a to the end and maybe lib to the
+# start to get the filename. Also allow objects.
+suffixes = [".lib", ".a", ".obj", ".o"]
+if not any([lib.endswith(s) for s in suffixes]):
+for s in suffixes:
+if os.path.exists(lib + s):
+lib = lib + s
+break
+if os.path.exists("lib" + lib + s):
+lib = "lib" + lib + s
+break

River707 wrote:

Tried this, but it actually ends up being a bit more convoluted because there 
are two loops to break from instead of just one (either need to recheck the 
suffix, or use the weird `else` after for loop + continue/break)

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


[Lldb-commits] [lldb] [lldb] add stop-at-user-entry option to process launch (PR #67019)

2023-09-28 Thread via lldb-commits
=?utf-8?q?Jos=C3=A9?= L. Junior ,
=?utf-8?q?Jos=C3=A9?= L. Junior ,
=?utf-8?q?Jos=C3=A9?= L. Junior ,
=?utf-8?q?Jos=C3=A9?= L. Junior ,
=?utf-8?q?Jos=C3=A9?= L. Junior ,
=?utf-8?q?Jos=C3=A9?= L. Junior 
Message-ID:
In-Reply-To: 


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

Other than that trivial doc style comment, this LGTM.

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


[Lldb-commits] [lldb] [lldb] add stop-at-user-entry option to process launch (PR #67019)

2023-09-28 Thread via lldb-commits
=?utf-8?q?José?= L. Junior ,
=?utf-8?q?José?= L. Junior ,
=?utf-8?q?José?= L. Junior ,
=?utf-8?q?José?= L. Junior ,
=?utf-8?q?José?= L. Junior ,
=?utf-8?q?José?= L. Junior 
Message-ID:
In-Reply-To: 



@@ -38,7 +39,37 @@ Status CommandOptionsProcessLaunch::SetOptionValue(
   case 's': // Stop at program entry point
 launch_info.GetFlags().Set(eLaunchFlagStopAtEntry);
 break;
-
+  case 'm': // Stop at user entry point
+  {
+TargetSP target_sp =
+execution_context ? execution_context->GetTargetSP() : TargetSP();
+ModuleSP main_module_sp = target_sp->GetExecutableModule();
+FileSpecList shared_lib_filter;
+shared_lib_filter.Append(main_module_sp->GetFileSpec());
+std::set entryPointNamesSet;
+for (LanguageType lang_type : Language::GetSupportedLanguages()) {
+  Language *lang = Language::FindPlugin(lang_type);
+  if (lang) {
+std::string entryPointName = lang->GetUserEntryPointName();
+if (!entryPointName.empty())
+  entryPointNamesSet.insert(entryPointName);
+  }
+}
+std::vector entryPointNames(entryPointNamesSet.begin(),
+ entryPointNamesSet.end());
+BreakpointSP bp_sp = target_sp->CreateBreakpoint(
+/*containingModules=*/&shared_lib_filter,

jimingham wrote:

We tend to put this sort of doc comment after the variable rather than before, 
and don't put it on arguments where the variable name being passed (e.g. 
`shared_lib_filter`) is self-documenting.

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


[Lldb-commits] [lldb] [lldb] add stop-at-user-entry option to process launch (PR #67019)

2023-09-28 Thread via lldb-commits
=?utf-8?q?José?= L. Junior ,
=?utf-8?q?José?= L. Junior ,
=?utf-8?q?José?= L. Junior ,
=?utf-8?q?José?= L. Junior ,
=?utf-8?q?José?= L. Junior ,
=?utf-8?q?José?= L. Junior 
Message-ID:
In-Reply-To: 


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


[Lldb-commits] [lldb] [lldb] add stop-at-user-entry option to process launch (PR #67019)

2023-09-28 Thread José Lira Junior via lldb-commits


@@ -38,7 +39,37 @@ Status CommandOptionsProcessLaunch::SetOptionValue(
   case 's': // Stop at program entry point
 launch_info.GetFlags().Set(eLaunchFlagStopAtEntry);
 break;
-
+  case 'm': // Stop at user entry point
+  {
+TargetSP target_sp =
+execution_context ? execution_context->GetTargetSP() : TargetSP();
+ModuleSP main_module_sp = target_sp->GetExecutableModule();
+FileSpecList shared_lib_filter;
+shared_lib_filter.Append(main_module_sp->GetFileSpec());
+std::set entryPointNamesSet;
+for (LanguageType lang_type : Language::GetSupportedLanguages()) {
+  Language *lang = Language::FindPlugin(lang_type);
+  if (lang) {
+std::string entryPointName = lang->GetUserEntryPointName();
+if (!entryPointName.empty())
+  entryPointNamesSet.insert(entryPointName);
+  }
+}
+std::vector entryPointNames(entryPointNamesSet.begin(),
+ entryPointNamesSet.end());
+BreakpointSP bp_sp = target_sp->CreateBreakpoint(
+/*containingModules=*/&shared_lib_filter,

junior-jl wrote:

You mean like this?

```cpp
BreakpointSP bp_sp = target_sp->CreateBreakpoint(
&shared_lib_filter, 
nullptr, // containingSourceFiles
entryPointNames, 
eFunctionNameTypeFull,   // func_name_type_mask
eLanguageTypeUnknown,// language
0,   // offset
eLazyBoolNo, // skip_prologue
false// internal
false// hardware
);
```

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


[Lldb-commits] [lldb] [lldb] Add windows support for LLDB_EXPORT_ALL_SYMBOLS (PR #67628)

2023-09-28 Thread River Riddle via lldb-commits

https://github.com/River707 updated 
https://github.com/llvm/llvm-project/pull/67628

>From da965dd04c810f0bde7ed3353f13ce5d7d064d88 Mon Sep 17 00:00:00 2001
From: River Riddle 
Date: Wed, 27 Sep 2023 18:59:53 -0700
Subject: [PATCH] [lldb] Add windows support for LLDB_EXPORT_ALL_SYMBOLS

LLDB_EXPORT_ALL_SYMBOLS is useful when building out-of-tree
plugins and extensions that rely on LLDB's internal symbols. For
example, this is how the Mojo language provides its REPL and
debugger support.

Supporting this on windows is kind of tricky because this is normally
expected to be done using dllexport/dllimport, but lldb uses these
with the public api. This PR takes an approach similar to what LLVM
does with LLVM_EXPORT_SYMBOLS_FOR_PLUGINS, and what chromium
does for 
[abseil](https://github.com/chromium/chromium/blob/253d14e20fdc0cab05e5516770dceca18f9bddaf/third_party/abseil-cpp/generate_def_files.py),
and uses a python script to extract the necessary symbols by looking at
the symbol table for the various lldb libraries.
---
 lldb/cmake/modules/LLDBConfig.cmake  |  10 +-
 lldb/scripts/msvc_extract_private_symbols.py | 102 +++
 lldb/source/API/CMakeLists.txt   |  37 +++
 3 files changed, 141 insertions(+), 8 deletions(-)
 create mode 100644 lldb/scripts/msvc_extract_private_symbols.py

diff --git a/lldb/cmake/modules/LLDBConfig.cmake 
b/lldb/cmake/modules/LLDBConfig.cmake
index 19283b3cbb0194f..380016ce48015fa 100644
--- a/lldb/cmake/modules/LLDBConfig.cmake
+++ b/lldb/cmake/modules/LLDBConfig.cmake
@@ -122,14 +122,8 @@ if(APPLE AND CMAKE_GENERATOR STREQUAL Xcode)
   endif()
 endif()
 
-if (NOT CMAKE_SYSTEM_NAME MATCHES "Windows")
-  set(LLDB_EXPORT_ALL_SYMBOLS 0 CACHE BOOL
-"Causes lldb to export all symbols when building liblldb.")
-else()
-  # Windows doesn't support toggling this, so don't bother making it a
-  # cache variable.
-  set(LLDB_EXPORT_ALL_SYMBOLS 0)
-endif()
+set(LLDB_EXPORT_ALL_SYMBOLS 0 CACHE BOOL
+  "Causes lldb to export all symbols when building liblldb.")
 
 if ((NOT MSVC) OR MSVC12)
   add_definitions( -DHAVE_ROUND )
diff --git a/lldb/scripts/msvc_extract_private_symbols.py 
b/lldb/scripts/msvc_extract_private_symbols.py
new file mode 100644
index 000..05e8b0e2095ca33
--- /dev/null
+++ b/lldb/scripts/msvc_extract_private_symbols.py
@@ -0,0 +1,102 @@
+"""A tool for extracting a list of private lldb symbols to export for MSVC.
+
+When exporting symbols from a dll or exe we either need to mark the symbols in
+the source code as __declspec(dllexport) or supply a list of symbols to the
+linker. Private symbols in LLDB don't explicitly specific dllexport, so we
+automate that by examining the symbol table.
+"""
+
+import argparse
+import os
+import re
+import subprocess
+import sys
+
+
+def extract_symbols(nm_path: str, lib: str):
+"""Extract all of the private lldb symbols from the given path to llvm-nm 
and
+library to extract from."""
+
+# Matches mangled symbols containing 'lldb_private'.
+lldb_sym_re = r"0* [BT] (?P[?]+[^?].*lldb_private.*)"
+
+# '-g' means we only get global symbols.
+# '-p' do not waste time sorting the symbols.
+process = subprocess.Popen(
+[nm_path, "-g", "-p", lib],
+bufsize=1,
+stdout=subprocess.PIPE,
+stdin=subprocess.PIPE,
+universal_newlines=True,
+)
+process.stdin.close()
+
+lldb_symbols = set()
+for line in process.stdout:
+match = re.match(lldb_sym_re, line)
+if match:
+symbol = match.group("symbol")
+assert (
+symbol.count(" ") == 0
+), "Regex matched too much, probably got undecorated name as well"
+# Deleting destructors start with ?_G or ?_E and can be discarded
+# because link.exe gives you a warning telling you they can't be
+# exported if you don't.
+if symbol.startswith("??_G") or symbol.startswith("??_E"):
+continue
+lldb_symbols.add(symbol)
+
+return lldb_symbols
+
+
+def main():
+parser = argparse.ArgumentParser(description="Generate LLDB dll exports")
+parser.add_argument(
+"-o", metavar="file", type=str, help="The name of the resultant export 
file."
+)
+parser.add_argument("--nm", help="Path to the llvm-nm executable.")
+parser.add_argument(
+"libs",
+metavar="lib",
+type=str,
+nargs="+",
+help="The libraries to extract symbols from.",
+)
+args = parser.parse_args()
+
+# Get the list of libraries to extract symbols from
+libs = list()
+for lib in args.libs:
+# When invoked by cmake the arguments are the cmake target names of the
+# libraries, so we need to add .lib/.a to the end and maybe lib to the
+# start to get the filename. Also allow objects.
+suffixes = [".lib", ".a", ".obj", ".o"]
+if not any([lib.endswith(s) for s in suffixes]):
+ 

[Lldb-commits] [lldb] [lldb] add stop-at-user-entry option to process launch (PR #67019)

2023-09-28 Thread Michael Buch via lldb-commits
=?utf-8?q?José?= L. Junior ,
=?utf-8?q?José?= L. Junior ,
=?utf-8?q?José?= L. Junior ,
=?utf-8?q?José?= L. Junior ,
=?utf-8?q?José?= L. Junior ,
=?utf-8?q?José?= L. Junior 
Message-ID:
In-Reply-To: 



@@ -38,7 +39,37 @@ Status CommandOptionsProcessLaunch::SetOptionValue(
   case 's': // Stop at program entry point
 launch_info.GetFlags().Set(eLaunchFlagStopAtEntry);
 break;
-
+  case 'm': // Stop at user entry point
+  {
+TargetSP target_sp =
+execution_context ? execution_context->GetTargetSP() : TargetSP();
+ModuleSP main_module_sp = target_sp->GetExecutableModule();
+FileSpecList shared_lib_filter;
+shared_lib_filter.Append(main_module_sp->GetFileSpec());
+std::set entryPointNamesSet;
+for (LanguageType lang_type : Language::GetSupportedLanguages()) {
+  Language *lang = Language::FindPlugin(lang_type);
+  if (lang) {
+std::string entryPointName = lang->GetUserEntryPointName();
+if (!entryPointName.empty())
+  entryPointNamesSet.insert(entryPointName);
+  }
+}
+std::vector entryPointNames(entryPointNamesSet.begin(),

Michael137 wrote:

Feel free to ignore

llvm has a `SetVector` type that you could consider using here (it allows you 
to specify the underlying `vector` container too; then calling 
`SetVector::takeVector()` will give you the container)

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


[Lldb-commits] [lldb] [lldb] add stop-at-user-entry option to process launch (PR #67019)

2023-09-28 Thread via lldb-commits
=?utf-8?q?Jos=C3=A9?= L. Junior ,
=?utf-8?q?Jos=C3=A9?= L. Junior ,
=?utf-8?q?Jos=C3=A9?= L. Junior ,
=?utf-8?q?Jos=C3=A9?= L. Junior ,
=?utf-8?q?Jos=C3=A9?= L. Junior ,
=?utf-8?q?Jos=C3=A9?= L. Junior 
Message-ID:
In-Reply-To: 



@@ -38,7 +39,37 @@ Status CommandOptionsProcessLaunch::SetOptionValue(
   case 's': // Stop at program entry point
 launch_info.GetFlags().Set(eLaunchFlagStopAtEntry);
 break;
-
+  case 'm': // Stop at user entry point
+  {
+TargetSP target_sp =
+execution_context ? execution_context->GetTargetSP() : TargetSP();
+ModuleSP main_module_sp = target_sp->GetExecutableModule();
+FileSpecList shared_lib_filter;
+shared_lib_filter.Append(main_module_sp->GetFileSpec());
+std::set entryPointNamesSet;
+for (LanguageType lang_type : Language::GetSupportedLanguages()) {
+  Language *lang = Language::FindPlugin(lang_type);
+  if (lang) {
+std::string entryPointName = lang->GetUserEntryPointName();
+if (!entryPointName.empty())
+  entryPointNamesSet.insert(entryPointName);
+  }
+}
+std::vector entryPointNames(entryPointNamesSet.begin(),
+ entryPointNamesSet.end());
+BreakpointSP bp_sp = target_sp->CreateBreakpoint(
+/*containingModules=*/&shared_lib_filter,

jimingham wrote:

Yes.

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


[Lldb-commits] [lldb] Add the ability to get a C++ vtable ValueObject from another ValueObj… (PR #67599)

2023-09-28 Thread Greg Clayton via lldb-commits

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

>From 8fa9aae354ac455f4ea443de1bb5f753fe93fb51 Mon Sep 17 00:00:00 2001
From: Greg Clayton 
Date: Wed, 27 Sep 2023 13:03:40 -0700
Subject: [PATCH 1/2] Add the ability to get a C++ vtable ValueObject from
 another ValueObject.

This patch adds the ability to ask a ValueObject for a ValueObject that 
represents the virtual function table for a C++ class. If the ValueObject is 
not a C++ class with a vtable, a valid ValueObject value will be returned that 
contains an appropriate error. If it is successful a valid ValueObject that 
represents vtable will be returned. The ValueObject that is returned will have 
a name that matches the demangled value for a C++ vtable mangled name like 
"vtable for ". It will have N children, one for each virtual 
function pointer. Each child's value is the function pointer itself, the 
summary is the symbolication of this function pointer, and the type will be a 
valid function pointer from the debug info if there is debug information 
corresponding to the virtual function pointer.

The vtable SBValue will have the following:
- SBValue::GetName() returns "vtable for "
- SBValue::GetValue() returns a string representation of the vtable address
- SBValue::GetSummary() returns NULL
- SBValue::GetType() returns a type appropriate for a uintptr_t type for the 
current process
- SBValue::GetLoadAddress() returns the address of the vtable adderess
- SBValue::GetValueAsUnsigned(...) returns the vtable address
- SBValue::GetNumChildren() returns the number of virtual function pointers in 
the vtable
- SBValue::GetChildAtIndex(...) returns a SBValue that represents a virtual 
function pointer

The child SBValue objects that represent a virtual function pointer has the 
following values:
- SBValue::GetName() returns "[%u]" where %u is the vtable function pointer 
index
- SBValue::GetValue() returns a string representation of the virtual function 
pointer
- SBValue::GetSummary() returns a symbolicated respresentation of the virtual 
function pointer
- SBValue::GetType() returns the function prototype type if there is debug 
info, or a generic funtion prototype if there is no debug info
- SBValue::GetLoadAddress() returns the address of the virtual function pointer
- SBValue::GetValueAsUnsigned(...) returns the virtual function pointer
- SBValue::GetNumChildren() returns 0
- SBValue::GetChildAtIndex(...) returns invalid SBValue for any index

Examples of using this API via python:

```
(lldb) script vtable = lldb.frame.FindVariable("shape_ptr").GetVTable()
(lldb) script vtable
vtable for Shape = 0x00014088 {
  [0] = 0x00013d20 a.out`Shape::~Shape() at main.cpp:3
  [1] = 0x00013e4c a.out`Shape::~Shape() at main.cpp:3
  [2] = 0x00013e7c a.out`Shape::area() at main.cpp:4
  [3] = 0x00013e3c a.out`Shape::optional() at main.cpp:7
}
(lldb) script c = vtable.GetChildAtIndex(0)
(lldb) script c
(void ()) [0] = 0x00013d20 a.out`Shape::~Shape() at main.cpp:3
```
---
 lldb/include/lldb/API/SBValue.h   |  28 ++
 lldb/include/lldb/Core/ValueObject.h  |   4 +
 lldb/include/lldb/Core/ValueObjectChild.h |   1 +
 lldb/include/lldb/Core/ValueObjectVTable.h|  65 
 lldb/include/lldb/Symbol/TypeSystem.h |   4 +
 lldb/include/lldb/lldb-enumerations.h |   4 +-
 lldb/source/API/SBValue.cpp   |  17 +-
 lldb/source/Commands/CommandObjectFrame.cpp   |   2 +
 lldb/source/Core/CMakeLists.txt   |   1 +
 lldb/source/Core/ValueObject.cpp  |   5 +
 lldb/source/Core/ValueObjectVTable.cpp| 325 ++
 .../DataFormatters/CXXFunctionPointer.cpp |   6 +-
 .../Language/CPlusPlus/CPlusPlusLanguage.cpp  |   4 +-
 .../TypeSystem/Clang/TypeSystemClang.cpp  |  26 +-
 .../TypeSystem/Clang/TypeSystemClang.h|   4 +
 lldb/test/API/functionalities/vtable/Makefile |   3 +
 .../functionalities/vtable/TestVTableValue.py | 135 
 lldb/test/API/functionalities/vtable/main.cpp |  37 ++
 18 files changed, 664 insertions(+), 7 deletions(-)
 create mode 100644 lldb/include/lldb/Core/ValueObjectVTable.h
 create mode 100644 lldb/source/Core/ValueObjectVTable.cpp
 create mode 100644 lldb/test/API/functionalities/vtable/Makefile
 create mode 100644 lldb/test/API/functionalities/vtable/TestVTableValue.py
 create mode 100644 lldb/test/API/functionalities/vtable/main.cpp

diff --git a/lldb/include/lldb/API/SBValue.h b/lldb/include/lldb/API/SBValue.h
index b66c2d5642b6f95..333bdf1738eecaf 100644
--- a/lldb/include/lldb/API/SBValue.h
+++ b/lldb/include/lldb/API/SBValue.h
@@ -374,6 +374,34 @@ class LLDB_API SBValue {
   lldb::SBWatchpoint WatchPointee(bool resolve_location, bool read, bool write,
   SBError &error);
 
+  /// If this value represents a C++ class that has a vtable, return an value
+  /// that represents the virtual function table.
+  ///
+  /// SBValu

[Lldb-commits] [lldb] [InstCombine] Canonicalize `and(zext(A), B)` into `select A, B & 1, 0` (PR #66740)

2023-09-28 Thread Yingwei Zheng via lldb-commits

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


[Lldb-commits] [lldb] Add the ability to get a C++ vtable ValueObject from another ValueObj… (PR #67599)

2023-09-28 Thread Greg Clayton via lldb-commits

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

>From 8fa9aae354ac455f4ea443de1bb5f753fe93fb51 Mon Sep 17 00:00:00 2001
From: Greg Clayton 
Date: Wed, 27 Sep 2023 13:03:40 -0700
Subject: [PATCH 1/3] Add the ability to get a C++ vtable ValueObject from
 another ValueObject.

This patch adds the ability to ask a ValueObject for a ValueObject that 
represents the virtual function table for a C++ class. If the ValueObject is 
not a C++ class with a vtable, a valid ValueObject value will be returned that 
contains an appropriate error. If it is successful a valid ValueObject that 
represents vtable will be returned. The ValueObject that is returned will have 
a name that matches the demangled value for a C++ vtable mangled name like 
"vtable for ". It will have N children, one for each virtual 
function pointer. Each child's value is the function pointer itself, the 
summary is the symbolication of this function pointer, and the type will be a 
valid function pointer from the debug info if there is debug information 
corresponding to the virtual function pointer.

The vtable SBValue will have the following:
- SBValue::GetName() returns "vtable for "
- SBValue::GetValue() returns a string representation of the vtable address
- SBValue::GetSummary() returns NULL
- SBValue::GetType() returns a type appropriate for a uintptr_t type for the 
current process
- SBValue::GetLoadAddress() returns the address of the vtable adderess
- SBValue::GetValueAsUnsigned(...) returns the vtable address
- SBValue::GetNumChildren() returns the number of virtual function pointers in 
the vtable
- SBValue::GetChildAtIndex(...) returns a SBValue that represents a virtual 
function pointer

The child SBValue objects that represent a virtual function pointer has the 
following values:
- SBValue::GetName() returns "[%u]" where %u is the vtable function pointer 
index
- SBValue::GetValue() returns a string representation of the virtual function 
pointer
- SBValue::GetSummary() returns a symbolicated respresentation of the virtual 
function pointer
- SBValue::GetType() returns the function prototype type if there is debug 
info, or a generic funtion prototype if there is no debug info
- SBValue::GetLoadAddress() returns the address of the virtual function pointer
- SBValue::GetValueAsUnsigned(...) returns the virtual function pointer
- SBValue::GetNumChildren() returns 0
- SBValue::GetChildAtIndex(...) returns invalid SBValue for any index

Examples of using this API via python:

```
(lldb) script vtable = lldb.frame.FindVariable("shape_ptr").GetVTable()
(lldb) script vtable
vtable for Shape = 0x00014088 {
  [0] = 0x00013d20 a.out`Shape::~Shape() at main.cpp:3
  [1] = 0x00013e4c a.out`Shape::~Shape() at main.cpp:3
  [2] = 0x00013e7c a.out`Shape::area() at main.cpp:4
  [3] = 0x00013e3c a.out`Shape::optional() at main.cpp:7
}
(lldb) script c = vtable.GetChildAtIndex(0)
(lldb) script c
(void ()) [0] = 0x00013d20 a.out`Shape::~Shape() at main.cpp:3
```
---
 lldb/include/lldb/API/SBValue.h   |  28 ++
 lldb/include/lldb/Core/ValueObject.h  |   4 +
 lldb/include/lldb/Core/ValueObjectChild.h |   1 +
 lldb/include/lldb/Core/ValueObjectVTable.h|  65 
 lldb/include/lldb/Symbol/TypeSystem.h |   4 +
 lldb/include/lldb/lldb-enumerations.h |   4 +-
 lldb/source/API/SBValue.cpp   |  17 +-
 lldb/source/Commands/CommandObjectFrame.cpp   |   2 +
 lldb/source/Core/CMakeLists.txt   |   1 +
 lldb/source/Core/ValueObject.cpp  |   5 +
 lldb/source/Core/ValueObjectVTable.cpp| 325 ++
 .../DataFormatters/CXXFunctionPointer.cpp |   6 +-
 .../Language/CPlusPlus/CPlusPlusLanguage.cpp  |   4 +-
 .../TypeSystem/Clang/TypeSystemClang.cpp  |  26 +-
 .../TypeSystem/Clang/TypeSystemClang.h|   4 +
 lldb/test/API/functionalities/vtable/Makefile |   3 +
 .../functionalities/vtable/TestVTableValue.py | 135 
 lldb/test/API/functionalities/vtable/main.cpp |  37 ++
 18 files changed, 664 insertions(+), 7 deletions(-)
 create mode 100644 lldb/include/lldb/Core/ValueObjectVTable.h
 create mode 100644 lldb/source/Core/ValueObjectVTable.cpp
 create mode 100644 lldb/test/API/functionalities/vtable/Makefile
 create mode 100644 lldb/test/API/functionalities/vtable/TestVTableValue.py
 create mode 100644 lldb/test/API/functionalities/vtable/main.cpp

diff --git a/lldb/include/lldb/API/SBValue.h b/lldb/include/lldb/API/SBValue.h
index b66c2d5642b6f95..333bdf1738eecaf 100644
--- a/lldb/include/lldb/API/SBValue.h
+++ b/lldb/include/lldb/API/SBValue.h
@@ -374,6 +374,34 @@ class LLDB_API SBValue {
   lldb::SBWatchpoint WatchPointee(bool resolve_location, bool read, bool write,
   SBError &error);
 
+  /// If this value represents a C++ class that has a vtable, return an value
+  /// that represents the virtual function table.
+  ///
+  /// SBValu

[Lldb-commits] [lldb] Add the ability to get a C++ vtable ValueObject from another ValueObj… (PR #67599)

2023-09-28 Thread Greg Clayton via lldb-commits

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


[Lldb-commits] [lldb] Add the ability to get a C++ vtable ValueObject from another ValueObj… (PR #67599)

2023-09-28 Thread Greg Clayton via lldb-commits


@@ -0,0 +1,325 @@
+//===-- ValueObjectVTable.cpp 
-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+
+#include "lldb/Core/ValueObjectVTable.h"
+#include "lldb/Core/Module.h"
+#include "lldb/Core/ValueObjectChild.h"
+#include "lldb/Symbol/Function.h"
+#include "lldb/lldb-defines.h"
+#include "lldb/lldb-enumerations.h"
+#include "lldb/lldb-forward.h"
+#include "lldb/lldb-private-enumerations.h"
+#include "clang/Tooling/Transformer/RangeSelector.h"
+#include "llvm/Support/MathExtras.h"
+#include 
+
+using namespace lldb;
+using namespace lldb_private;
+
+class ValueObjectVTableChild : public ValueObject {
+public:
+  ValueObjectVTableChild(ValueObject &parent, uint32_t func_idx,
+ uint64_t addr_size)
+  : ValueObject(parent), m_func_idx(func_idx), m_addr_size(addr_size) {
+SetFormat(eFormatPointer);
+SetName(ConstString(llvm::formatv("[{0}]", func_idx).str()));
+  }
+
+  ~ValueObjectVTableChild() override = default;
+
+  std::optional GetByteSize() override { return m_addr_size; };
+
+  size_t CalculateNumChildren(uint32_t max) override { return 0; };
+
+  ValueType GetValueType() const override { return eValueTypeVTableEntry; };
+
+  bool IsInScope() override {
+ValueObject *parent = GetParent();
+if (parent)
+  return parent->IsInScope();
+return false;
+  };
+
+protected:
+  bool UpdateValue() override {
+SetValueIsValid(false);
+m_value.Clear();
+ValueObject *parent = GetParent();
+if (!parent) {
+  m_error.SetErrorString("no parent object");
+  return false;
+}
+
+addr_t parent_addr = parent->GetValueAsUnsigned(LLDB_INVALID_ADDRESS);
+if (parent_addr == LLDB_INVALID_ADDRESS) {
+  m_error.SetErrorString("parent has invalid address");
+  return false;
+}
+
+ProcessSP process_sp = GetProcessSP();
+if (!process_sp) {
+  m_error.SetErrorString("no process");
+  return false;
+}
+
+TargetSP target_sp = GetTargetSP();
+if (!target_sp) {
+  m_error.SetErrorString("no target");
+  return false;
+}
+
+// Each `vtable_entry_addr` points to the function pointer.
+addr_t vtable_entry_addr = parent_addr + m_func_idx * m_addr_size;
+addr_t vfunc_ptr =
+process_sp->ReadPointerFromMemory(vtable_entry_addr, m_error);
+if (m_error.Fail()) {
+  m_error.SetErrorStringWithFormat(
+  "failed to read virtual function entry 0x%16.16" PRIx64,
+  vtable_entry_addr);
+  return false;
+}
+
+Address resolved_vfunc_ptr_address;
+target_sp->ResolveLoadAddress(vfunc_ptr, resolved_vfunc_ptr_address);
+if (!resolved_vfunc_ptr_address.IsValid()) {
+  m_error.SetErrorStringWithFormat(
+  "unable to resolve func ptr address: 0x%16.16" PRIx64, vfunc_ptr);
+  return false;
+}
+
+// Set our value to be the load address of the function pointer in memory
+// and our type to be the function pointer type.
+m_value.SetValueType(Value::ValueType::LoadAddress);
+m_value.GetScalar() = vtable_entry_addr;
+
+// See if our resolved address points to a function in the debug info. If
+// it does, then we can report the type as a function prototype for this
+// function.
+Function *function =
+resolved_vfunc_ptr_address.CalculateSymbolContextFunction();
+if (function) {
+  m_value.SetCompilerType(function->GetCompilerType());
+} else {
+  // Set our value's compiler type to a generic function protoype so that
+  // it displays as a hex function pointer for the value and the summary
+  // will display the address description.
+  auto type_system_or_err =
+target_sp->GetScratchTypeSystemForLanguage(eLanguageTypeC_plus_plus);
+  if (type_system_or_err) {
+CompilerType proto = 
(*type_system_or_err)->CreateGenericFunctionPrototype();
+if (proto.IsFunctionType())
+  m_value.SetCompilerType(proto);
+  } else {
+consumeError(type_system_or_err.takeError());
+  }
+}
+
+// Now read our value into m_data so that our we can use the default
+// summary provider for C++ for function pointers which will get the
+// address description for our function pointer.
+if (m_error.Success()) {
+  const bool thread_and_frame_only_if_stopped = true;
+  ExecutionContext exe_ctx(
+GetExecutionContextRef().Lock(thread_and_frame_only_if_stopped));
+  m_error = m_value.GetValueAsData(&exe_ctx, m_data, GetModule().get());
+}
+SetValueDidChange(true);
+SetValueIsValid(true);
+return true;
+  };
+
+  CompilerType GetCompilerTypeImpl() override {
+return m_value.GetCompilerType();
+  }

[Lldb-commits] [lldb] Add the ability to get a C++ vtable ValueObject from another ValueObj… (PR #67599)

2023-09-28 Thread Greg Clayton via lldb-commits

https://github.com/clayborg commented:

Ok. I have address all review comments. Jim, please take a look at the 
LanguageRuntime changes to see if you agree on how I did things. Things 
factored out quite nicely I believe.

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


[Lldb-commits] [lldb] [lldb][NFCI] Move functionality for getting unsupported DW_FORM values (PR #67579)

2023-09-28 Thread Alex Langford via lldb-commits

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


[Lldb-commits] [lldb] 36a5183 - [lldb][NFCI] Move functionality for getting unsupported DW_FORM values (#67579)

2023-09-28 Thread via lldb-commits

Author: Alex Langford
Date: 2023-09-28T12:18:08-07:00
New Revision: 36a518317fdaab377830f8d18ead9301b06e9e8d

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

LOG: [lldb][NFCI] Move functionality for getting unsupported DW_FORM values 
(#67579)

The LLVM implementation of DWARFDebugAbbrev does not have a way of
listing all the DW_FORM values that have been parsed but are unsupported
or otherwise unknown. AFAICT this functionality does not exist in LLVM
at all. Since my primary goal is to unify the implementations and not
judge the usefulness or completeness of this functionality, I decided to
move it out of LLDB's implementation of DWARFDebugAbbrev for the time
being.

Added: 


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

Removed: 




diff  --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAbbrev.cpp 
b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAbbrev.cpp
index bcebba6abd3ee5c..f3c2755c5a527cc 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAbbrev.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAbbrev.cpp
@@ -61,13 +61,3 @@ DWARFDebugAbbrev::GetAbbreviationDeclarationSet(
 return &(pos->second);
   return nullptr;
 }
-
-// DWARFDebugAbbrev::GetUnsupportedForms()
-void DWARFDebugAbbrev::GetUnsupportedForms(
-std::set &invalid_forms) const {
-  for (const auto &pair : m_abbrevCollMap)
-for (const auto &decl : pair.second)
-  for (const auto &attr : decl.attributes())
-if (!DWARFFormValue::FormIsSupported(attr.Form))
-  invalid_forms.insert(attr.Form);
-}

diff  --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAbbrev.h 
b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAbbrev.h
index 6d0616deeb91038..d2fade0934c8a88 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAbbrev.h
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAbbrev.h
@@ -36,7 +36,15 @@ class DWARFDebugAbbrev {
   /// llvm::ErrorSuccess() on success, and an appropriate llvm::Error object
   /// otherwise.
   llvm::Error parse();
-  void GetUnsupportedForms(std::set &invalid_forms) const;
+
+  DWARFAbbreviationDeclarationCollMapConstIter begin() const {
+assert(!m_data && "Must call parse before iterating over 
DWARFDebugAbbrev");
+return m_abbrevCollMap.begin();
+  }
+
+  DWARFAbbreviationDeclarationCollMapConstIter end() const {
+return m_abbrevCollMap.end();
+  }
 
 protected:
   DWARFAbbreviationDeclarationCollMap m_abbrevCollMap;

diff  --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp 
b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
index 9832c324a2c0e55..aae481e2ae74177 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
@@ -511,6 +511,20 @@ bool SymbolFileDWARF::SupportedVersion(uint16_t version) {
   return version >= 2 && version <= 5;
 }
 
+static std::set GetUnsupportedForms(DWARFDebugAbbrev *debug_abbrev) 
{
+  if (!debug_abbrev)
+return {};
+
+  std::set unsupported_forms;
+  for (const auto &[_, decl_set] : *debug_abbrev)
+for (const auto &decl : decl_set)
+  for (const auto &attr : decl.attributes())
+if (!DWARFFormValue::FormIsSupported(attr.Form))
+  unsupported_forms.insert(attr.Form);
+
+  return unsupported_forms;
+}
+
 uint32_t SymbolFileDWARF::CalculateAbilities() {
   uint32_t abilities = 0;
   if (m_objfile_sp != nullptr) {
@@ -540,19 +554,15 @@ uint32_t SymbolFileDWARF::CalculateAbilities() {
 debug_abbrev_file_size = section->GetFileSize();
 
   DWARFDebugAbbrev *abbrev = DebugAbbrev();
-  if (abbrev) {
-std::set invalid_forms;
-abbrev->GetUnsupportedForms(invalid_forms);
-if (!invalid_forms.empty()) {
-  StreamString error;
-  error.Printf("unsupported DW_FORM value%s:",
-   invalid_forms.size() > 1 ? "s" : "");
-  for (auto form : invalid_forms)
-error.Printf(" %#x", form);
-  m_objfile_sp->GetModule()->ReportWarning(
-  "{0}", error.GetString().str().c_str());
-  return 0;
-}
+  std::set unsupported_forms = GetUnsupportedForms(abbrev);
+  if (!unsupported_forms.empty()) {
+StreamString error;
+error.Printf("unsupported DW_FORM value%s:",
+ unsupported_forms.size() > 1 ? "s" : "");
+for (auto form : unsupported_forms)
+  error.Printf(" %#x", form);
+m_objfile_sp->GetModule()->ReportWarning("{0}", error.GetString());
+return 0;
   }
 
   section =



___
lldb

[Lldb-commits] [lldb] [Clang] Fix crash when visting a fold expression in a default argument (PR #67514)

2023-09-28 Thread Shafik Yaghmour via lldb-commits

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


[Lldb-commits] [lldb] Add the ability to get a C++ vtable ValueObject from another ValueObj… (PR #67599)

2023-09-28 Thread via lldb-commits

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


[Lldb-commits] [lldb] Add the ability to get a C++ vtable ValueObject from another ValueObj… (PR #67599)

2023-09-28 Thread via lldb-commits

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


[Lldb-commits] [lldb] Add the ability to get a C++ vtable ValueObject from another ValueObj… (PR #67599)

2023-09-28 Thread via lldb-commits


@@ -0,0 +1,298 @@
+//===-- ValueObjectVTable.cpp 
-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+
+#include "lldb/Core/ValueObjectVTable.h"
+#include "lldb/Core/Module.h"
+#include "lldb/Core/ValueObjectChild.h"
+#include "lldb/Symbol/Function.h"
+#include "lldb/Target/Language.h"
+#include "lldb/Target/LanguageRuntime.h"
+#include "lldb/lldb-defines.h"
+#include "lldb/lldb-enumerations.h"
+#include "lldb/lldb-forward.h"
+#include "lldb/lldb-private-enumerations.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+class ValueObjectVTableChild : public ValueObject {
+public:
+  ValueObjectVTableChild(ValueObject &parent, uint32_t func_idx,
+ uint64_t addr_size)
+  : ValueObject(parent), m_func_idx(func_idx), m_addr_size(addr_size) {
+SetFormat(eFormatPointer);
+SetName(ConstString(llvm::formatv("[{0}]", func_idx).str()));
+  }
+
+  ~ValueObjectVTableChild() override = default;
+
+  std::optional GetByteSize() override { return m_addr_size; };
+
+  size_t CalculateNumChildren(uint32_t max) override { return 0; };
+
+  ValueType GetValueType() const override { return eValueTypeVTableEntry; };
+
+  bool IsInScope() override {
+if (ValueObject *parent = GetParent())
+  return parent->IsInScope();
+return false;
+  };
+
+protected:
+  bool UpdateValue() override {
+SetValueIsValid(false);
+m_value.Clear();
+ValueObject *parent = GetParent();
+if (!parent) {
+  m_error.SetErrorString("no parent object");
+  return false;
+}
+
+addr_t parent_addr = parent->GetValueAsUnsigned(LLDB_INVALID_ADDRESS);
+if (parent_addr == LLDB_INVALID_ADDRESS) {
+  m_error.SetErrorString("parent has invalid address");
+  return false;
+}
+
+ProcessSP process_sp = GetProcessSP();
+if (!process_sp) {
+  m_error.SetErrorString("no process");
+  return false;
+}
+
+TargetSP target_sp = GetTargetSP();
+if (!target_sp) {
+  m_error.SetErrorString("no target");
+  return false;
+}
+
+// Each `vtable_entry_addr` points to the function pointer.
+addr_t vtable_entry_addr = parent_addr + m_func_idx * m_addr_size;
+addr_t vfunc_ptr =
+process_sp->ReadPointerFromMemory(vtable_entry_addr, m_error);
+if (m_error.Fail()) {
+  m_error.SetErrorStringWithFormat(
+  "failed to read virtual function entry 0x%16.16" PRIx64,
+  vtable_entry_addr);
+  return false;
+}
+
+
+// Set our value to be the load address of the function pointer in memory
+// and our type to be the function pointer type.
+m_value.SetValueType(Value::ValueType::LoadAddress);
+m_value.GetScalar() = vtable_entry_addr;
+
+// See if our resolved address points to a function in the debug info. If
+// it does, then we can report the type as a function prototype for this
+// function.
+Function *function = nullptr;
+Address resolved_vfunc_ptr_address;
+target_sp->ResolveLoadAddress(vfunc_ptr, resolved_vfunc_ptr_address);
+if (resolved_vfunc_ptr_address.IsValid())
+  function = resolved_vfunc_ptr_address.CalculateSymbolContextFunction();
+if (function) {
+  m_value.SetCompilerType(function->GetCompilerType().GetPointerType());
+} else {
+  // Set our value's compiler type to a generic function protoype so that
+  // it displays as a hex function pointer for the value and the summary
+  // will display the address description.
+
+  // Get the original type that this vtable is based off of so we can get
+  // the language from it correctly.
+  ValueObject *val = parent->GetParent();
+  auto type_system = target_sp->GetScratchTypeSystemForLanguage(
+val ? val->GetObjectRuntimeLanguage() : eLanguageTypeC_plus_plus);
+  if (type_system) {
+m_value.SetCompilerType(
+(*type_system)->CreateGenericFunctionPrototype().GetPointerType());
+  } else {
+consumeError(type_system.takeError());
+  }
+}
+
+// Now read our value into m_data so that our we can use the default
+// summary provider for C++ for function pointers which will get the
+// address description for our function pointer.
+if (m_error.Success()) {
+  const bool thread_and_frame_only_if_stopped = true;
+  ExecutionContext exe_ctx(
+GetExecutionContextRef().Lock(thread_and_frame_only_if_stopped));
+  m_error = m_value.GetValueAsData(&exe_ctx, m_data, GetModule().get());
+}
+SetValueDidChange(true);
+SetValueIsValid(true);
+return true;
+  };
+
+  CompilerType GetCompilerTypeImpl() override {
+return m_value.GetCompilerType();
+  };
+
+  const 

[Lldb-commits] [lldb] Add the ability to get a C++ vtable ValueObject from another ValueObj… (PR #67599)

2023-09-28 Thread via lldb-commits


@@ -54,134 +54,182 @@ bool 
ItaniumABILanguageRuntime::CouldHaveDynamicValue(ValueObject &in_value) {
   check_objc);
 }
 
-TypeAndOrName ItaniumABILanguageRuntime::GetTypeInfoFromVTableAddress(
-ValueObject &in_value, lldb::addr_t original_ptr,
-lldb::addr_t vtable_load_addr) {
-  if (m_process && vtable_load_addr != LLDB_INVALID_ADDRESS) {
-// Find the symbol that contains the "vtable_load_addr" address
-Address vtable_addr;
-Target &target = m_process->GetTarget();
-if (!target.GetSectionLoadList().IsEmpty()) {
-  if (target.GetSectionLoadList().ResolveLoadAddress(vtable_load_addr,
- vtable_addr)) {
-// See if we have cached info for this type already
-TypeAndOrName type_info = GetDynamicTypeInfo(vtable_addr);
-if (type_info)
-  return type_info;
-
-SymbolContext sc;
-target.GetImages().ResolveSymbolContextForAddress(
-vtable_addr, eSymbolContextSymbol, sc);
-Symbol *symbol = sc.symbol;
-if (symbol != nullptr) {
-  const char *name =
-  symbol->GetMangled().GetDemangledName().AsCString();
-  if (name && strstr(name, vtable_demangled_prefix) == name) {
-Log *log = GetLog(LLDBLog::Object);
-LLDB_LOGF(log,
-  "0x%16.16" PRIx64
-  ": static-type = '%s' has vtable symbol '%s'\n",
-  original_ptr, in_value.GetTypeName().GetCString(), name);
-// We are a C++ class, that's good.  Get the class name and look it
-// up:
-const char *class_name = name + strlen(vtable_demangled_prefix);
-// We know the class name is absolute, so tell FindTypes that by
-// prefixing it with the root namespace:
-std::string lookup_name("::");
-lookup_name.append(class_name);
-
-type_info.SetName(class_name);
-const bool exact_match = true;
-TypeList class_types;
-
-// First look in the module that the vtable symbol came from and
-// look for a single exact match.
-llvm::DenseSet searched_symbol_files;
-if (sc.module_sp)
-  sc.module_sp->FindTypes(ConstString(lookup_name), exact_match, 1,
+TypeAndOrName ItaniumABILanguageRuntime::GetTypeInfo(
+ValueObject &in_value, const VTableInfo &vtable_info) {
+  if (vtable_info.addr.IsSectionOffset()) {
+// See if we have cached info for this type already
+TypeAndOrName type_info = GetDynamicTypeInfo(vtable_info.addr);
+if (type_info)
+  return type_info;
+
+if (vtable_info.symbol) {
+  Log *log = GetLog(LLDBLog::Object);
+  llvm::StringRef symbol_name =
+  vtable_info.symbol->GetMangled().GetDemangledName().GetStringRef();
+  LLDB_LOGF(log,
+"0x%16.16" PRIx64
+": static-type = '%s' has vtable symbol '%s'\n",
+in_value.GetPointerValue(),
+in_value.GetTypeName().GetCString(),
+symbol_name.str().c_str());
+  // We are a C++ class, that's good.  Get the class name and look it
+  // up:
+  llvm::StringRef class_name = symbol_name;
+  class_name.consume_front(vtable_demangled_prefix);
+  // We know the class name is absolute, so tell FindTypes that by
+  // prefixing it with the root namespace:
+  std::string lookup_name("::");
+  lookup_name.append(class_name.data(), class_name.size());
+
+  type_info.SetName(class_name);
+  const bool exact_match = true;
+  TypeList class_types;
+
+  // First look in the module that the vtable symbol came from and
+  // look for a single exact match.
+  llvm::DenseSet searched_symbol_files;
+  ModuleSP module_sp = vtable_info.symbol->CalculateSymbolContextModule();
+  if (module_sp)
+module_sp->FindTypes(ConstString(lookup_name), exact_match, 1,
+  searched_symbol_files, class_types);
+
+  // If we didn't find a symbol, then move on to the entire module
+  // list in the target and get as many unique matches as possible
+  Target &target = m_process->GetTarget();
+  if (class_types.Empty())
+target.GetImages().FindTypes(nullptr, ConstString(lookup_name),
+  exact_match, UINT32_MAX,
   searched_symbol_files, class_types);
 
-// If we didn't find a symbol, then move on to the entire module
-// list in the target and get as many unique matches as possible
-if (class_types.Empty())
-  target.GetImages().FindTypes(nullptr, ConstString(lookup_name),
-   exact_match, UINT32_MAX,
-   searched_symbol_files,

[Lldb-commits] [lldb] Add the ability to get a C++ vtable ValueObject from another ValueObj… (PR #67599)

2023-09-28 Thread via lldb-commits

https://github.com/jimingham commented:

This is much nicer looking!

I had a couple small comments about apportioning duties between the 
ValueObjectVTable::Update and the GetVTableInfo in the comments.

It doesn't look like you handled corrupted tables yet?  Are you still intending 
to do that?

Another thing it might be good to test - though from what you've done it should 
indeed work is if I have:

BaseClass Foo my_foo = FirstChildOfFoo();
// Stop after this line and do `vtbl = 
frame.FindVariable("my_foo").GetVTable()` and check the vtable has the right 
functions for FirstChildOfFoo()
my_foo = SecondChildOfFoo();
// Stop after this line and check the `vtbl` variable again, it should now have 
the functions for SecondChildOfFoo...

That will make sure both that we notice the change in the parent & update the 
vtable appropriately, and that we don't mess up the memory management, such 
that holding onto just the vtable child doesn't keep the whole tree valid.

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


[Lldb-commits] [lldb] Add the ability to get a C++ vtable ValueObject from another ValueObj… (PR #67599)

2023-09-28 Thread via lldb-commits


@@ -0,0 +1,298 @@
+//===-- ValueObjectVTable.cpp 
-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+
+#include "lldb/Core/ValueObjectVTable.h"
+#include "lldb/Core/Module.h"
+#include "lldb/Core/ValueObjectChild.h"
+#include "lldb/Symbol/Function.h"
+#include "lldb/Target/Language.h"
+#include "lldb/Target/LanguageRuntime.h"
+#include "lldb/lldb-defines.h"
+#include "lldb/lldb-enumerations.h"
+#include "lldb/lldb-forward.h"
+#include "lldb/lldb-private-enumerations.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+class ValueObjectVTableChild : public ValueObject {
+public:
+  ValueObjectVTableChild(ValueObject &parent, uint32_t func_idx,
+ uint64_t addr_size)
+  : ValueObject(parent), m_func_idx(func_idx), m_addr_size(addr_size) {
+SetFormat(eFormatPointer);
+SetName(ConstString(llvm::formatv("[{0}]", func_idx).str()));
+  }
+
+  ~ValueObjectVTableChild() override = default;
+
+  std::optional GetByteSize() override { return m_addr_size; };
+
+  size_t CalculateNumChildren(uint32_t max) override { return 0; };
+
+  ValueType GetValueType() const override { return eValueTypeVTableEntry; };
+
+  bool IsInScope() override {
+if (ValueObject *parent = GetParent())
+  return parent->IsInScope();
+return false;
+  };
+
+protected:
+  bool UpdateValue() override {
+SetValueIsValid(false);
+m_value.Clear();
+ValueObject *parent = GetParent();
+if (!parent) {
+  m_error.SetErrorString("no parent object");
+  return false;
+}
+
+addr_t parent_addr = parent->GetValueAsUnsigned(LLDB_INVALID_ADDRESS);
+if (parent_addr == LLDB_INVALID_ADDRESS) {
+  m_error.SetErrorString("parent has invalid address");
+  return false;
+}
+
+ProcessSP process_sp = GetProcessSP();
+if (!process_sp) {
+  m_error.SetErrorString("no process");
+  return false;
+}
+
+TargetSP target_sp = GetTargetSP();
+if (!target_sp) {
+  m_error.SetErrorString("no target");
+  return false;
+}
+
+// Each `vtable_entry_addr` points to the function pointer.
+addr_t vtable_entry_addr = parent_addr + m_func_idx * m_addr_size;
+addr_t vfunc_ptr =
+process_sp->ReadPointerFromMemory(vtable_entry_addr, m_error);
+if (m_error.Fail()) {
+  m_error.SetErrorStringWithFormat(
+  "failed to read virtual function entry 0x%16.16" PRIx64,
+  vtable_entry_addr);
+  return false;
+}
+
+
+// Set our value to be the load address of the function pointer in memory
+// and our type to be the function pointer type.
+m_value.SetValueType(Value::ValueType::LoadAddress);
+m_value.GetScalar() = vtable_entry_addr;
+
+// See if our resolved address points to a function in the debug info. If
+// it does, then we can report the type as a function prototype for this
+// function.
+Function *function = nullptr;
+Address resolved_vfunc_ptr_address;
+target_sp->ResolveLoadAddress(vfunc_ptr, resolved_vfunc_ptr_address);
+if (resolved_vfunc_ptr_address.IsValid())
+  function = resolved_vfunc_ptr_address.CalculateSymbolContextFunction();
+if (function) {
+  m_value.SetCompilerType(function->GetCompilerType().GetPointerType());
+} else {
+  // Set our value's compiler type to a generic function protoype so that
+  // it displays as a hex function pointer for the value and the summary
+  // will display the address description.
+
+  // Get the original type that this vtable is based off of so we can get
+  // the language from it correctly.
+  ValueObject *val = parent->GetParent();
+  auto type_system = target_sp->GetScratchTypeSystemForLanguage(
+val ? val->GetObjectRuntimeLanguage() : eLanguageTypeC_plus_plus);
+  if (type_system) {
+m_value.SetCompilerType(
+(*type_system)->CreateGenericFunctionPrototype().GetPointerType());
+  } else {
+consumeError(type_system.takeError());
+  }
+}
+
+// Now read our value into m_data so that our we can use the default
+// summary provider for C++ for function pointers which will get the
+// address description for our function pointer.
+if (m_error.Success()) {
+  const bool thread_and_frame_only_if_stopped = true;
+  ExecutionContext exe_ctx(
+GetExecutionContextRef().Lock(thread_and_frame_only_if_stopped));
+  m_error = m_value.GetValueAsData(&exe_ctx, m_data, GetModule().get());
+}
+SetValueDidChange(true);
+SetValueIsValid(true);
+return true;
+  };
+
+  CompilerType GetCompilerTypeImpl() override {
+return m_value.GetCompilerType();
+  };
+
+  const 

[Lldb-commits] [lldb] Add the ability to get a C++ vtable ValueObject from another ValueObj… (PR #67599)

2023-09-28 Thread via lldb-commits


@@ -0,0 +1,325 @@
+//===-- ValueObjectVTable.cpp 
-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+
+#include "lldb/Core/ValueObjectVTable.h"
+#include "lldb/Core/Module.h"
+#include "lldb/Core/ValueObjectChild.h"
+#include "lldb/Symbol/Function.h"
+#include "lldb/lldb-defines.h"
+#include "lldb/lldb-enumerations.h"
+#include "lldb/lldb-forward.h"
+#include "lldb/lldb-private-enumerations.h"
+#include "clang/Tooling/Transformer/RangeSelector.h"
+#include "llvm/Support/MathExtras.h"
+#include 
+
+using namespace lldb;
+using namespace lldb_private;
+
+class ValueObjectVTableChild : public ValueObject {
+public:
+  ValueObjectVTableChild(ValueObject &parent, uint32_t func_idx,
+ uint64_t addr_size)
+  : ValueObject(parent), m_func_idx(func_idx), m_addr_size(addr_size) {
+SetFormat(eFormatPointer);
+SetName(ConstString(llvm::formatv("[{0}]", func_idx).str()));
+  }
+
+  ~ValueObjectVTableChild() override = default;
+
+  std::optional GetByteSize() override { return m_addr_size; };
+
+  size_t CalculateNumChildren(uint32_t max) override { return 0; };
+
+  ValueType GetValueType() const override { return eValueTypeVTableEntry; };
+
+  bool IsInScope() override {
+ValueObject *parent = GetParent();
+if (parent)
+  return parent->IsInScope();
+return false;
+  };
+
+protected:
+  bool UpdateValue() override {
+SetValueIsValid(false);
+m_value.Clear();
+ValueObject *parent = GetParent();
+if (!parent) {
+  m_error.SetErrorString("no parent object");
+  return false;
+}
+
+addr_t parent_addr = parent->GetValueAsUnsigned(LLDB_INVALID_ADDRESS);
+if (parent_addr == LLDB_INVALID_ADDRESS) {
+  m_error.SetErrorString("parent has invalid address");
+  return false;
+}
+
+ProcessSP process_sp = GetProcessSP();
+if (!process_sp) {
+  m_error.SetErrorString("no process");
+  return false;
+}
+
+TargetSP target_sp = GetTargetSP();
+if (!target_sp) {
+  m_error.SetErrorString("no target");
+  return false;
+}
+
+// Each `vtable_entry_addr` points to the function pointer.
+addr_t vtable_entry_addr = parent_addr + m_func_idx * m_addr_size;
+addr_t vfunc_ptr =
+process_sp->ReadPointerFromMemory(vtable_entry_addr, m_error);
+if (m_error.Fail()) {
+  m_error.SetErrorStringWithFormat(
+  "failed to read virtual function entry 0x%16.16" PRIx64,
+  vtable_entry_addr);
+  return false;
+}
+
+Address resolved_vfunc_ptr_address;
+target_sp->ResolveLoadAddress(vfunc_ptr, resolved_vfunc_ptr_address);
+if (!resolved_vfunc_ptr_address.IsValid()) {
+  m_error.SetErrorStringWithFormat(
+  "unable to resolve func ptr address: 0x%16.16" PRIx64, vfunc_ptr);
+  return false;
+}
+
+// Set our value to be the load address of the function pointer in memory
+// and our type to be the function pointer type.
+m_value.SetValueType(Value::ValueType::LoadAddress);
+m_value.GetScalar() = vtable_entry_addr;
+
+// See if our resolved address points to a function in the debug info. If
+// it does, then we can report the type as a function prototype for this
+// function.
+Function *function =
+resolved_vfunc_ptr_address.CalculateSymbolContextFunction();
+if (function) {
+  m_value.SetCompilerType(function->GetCompilerType());
+} else {
+  // Set our value's compiler type to a generic function protoype so that
+  // it displays as a hex function pointer for the value and the summary
+  // will display the address description.
+  auto type_system_or_err =
+target_sp->GetScratchTypeSystemForLanguage(eLanguageTypeC_plus_plus);
+  if (type_system_or_err) {
+CompilerType proto = 
(*type_system_or_err)->CreateGenericFunctionPrototype();
+if (proto.IsFunctionType())
+  m_value.SetCompilerType(proto);
+  } else {
+consumeError(type_system_or_err.takeError());
+  }
+}
+
+// Now read our value into m_data so that our we can use the default
+// summary provider for C++ for function pointers which will get the
+// address description for our function pointer.
+if (m_error.Success()) {
+  const bool thread_and_frame_only_if_stopped = true;
+  ExecutionContext exe_ctx(
+GetExecutionContextRef().Lock(thread_and_frame_only_if_stopped));
+  m_error = m_value.GetValueAsData(&exe_ctx, m_data, GetModule().get());
+}
+SetValueDidChange(true);
+SetValueIsValid(true);
+return true;
+  };
+
+  CompilerType GetCompilerTypeImpl() override {
+return m_value.GetCompilerType();
+  }

[Lldb-commits] [lldb] Add the ability to get a C++ vtable ValueObject from another ValueObj… (PR #67599)

2023-09-28 Thread via lldb-commits

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


[Lldb-commits] [lldb] Add the ability to get a C++ vtable ValueObject from another ValueObj… (PR #67599)

2023-09-28 Thread via lldb-commits


@@ -374,6 +374,34 @@ class LLDB_API SBValue {
   lldb::SBWatchpoint WatchPointee(bool resolve_location, bool read, bool write,
   SBError &error);
 
+  /// If this value represents a C++ class that has a vtable, return an value
+  /// that represents the virtual function table.
+  ///
+  /// SBValue::GetError() will be in the success state if this value represents
+  /// a C++ class with a vtable, or an appropriate error describing that the
+  /// object isn't a C++ class with a vtable or not a C++ class.
+  ///
+  /// SBValue::GetName() will be the demangled symbol name for the virtual
+  /// function table like "vtable for Baseclass".

jimingham wrote:

Sounds good

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


[Lldb-commits] [lldb] Add the ability to get a C++ vtable ValueObject from another ValueObj… (PR #67599)

2023-09-28 Thread Greg Clayton via lldb-commits


@@ -0,0 +1,298 @@
+//===-- ValueObjectVTable.cpp 
-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+
+#include "lldb/Core/ValueObjectVTable.h"
+#include "lldb/Core/Module.h"
+#include "lldb/Core/ValueObjectChild.h"
+#include "lldb/Symbol/Function.h"
+#include "lldb/Target/Language.h"
+#include "lldb/Target/LanguageRuntime.h"
+#include "lldb/lldb-defines.h"
+#include "lldb/lldb-enumerations.h"
+#include "lldb/lldb-forward.h"
+#include "lldb/lldb-private-enumerations.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+class ValueObjectVTableChild : public ValueObject {
+public:
+  ValueObjectVTableChild(ValueObject &parent, uint32_t func_idx,
+ uint64_t addr_size)
+  : ValueObject(parent), m_func_idx(func_idx), m_addr_size(addr_size) {
+SetFormat(eFormatPointer);
+SetName(ConstString(llvm::formatv("[{0}]", func_idx).str()));
+  }
+
+  ~ValueObjectVTableChild() override = default;
+
+  std::optional GetByteSize() override { return m_addr_size; };
+
+  size_t CalculateNumChildren(uint32_t max) override { return 0; };
+
+  ValueType GetValueType() const override { return eValueTypeVTableEntry; };
+
+  bool IsInScope() override {
+if (ValueObject *parent = GetParent())
+  return parent->IsInScope();
+return false;
+  };
+
+protected:
+  bool UpdateValue() override {
+SetValueIsValid(false);
+m_value.Clear();
+ValueObject *parent = GetParent();
+if (!parent) {
+  m_error.SetErrorString("no parent object");
+  return false;
+}
+
+addr_t parent_addr = parent->GetValueAsUnsigned(LLDB_INVALID_ADDRESS);
+if (parent_addr == LLDB_INVALID_ADDRESS) {
+  m_error.SetErrorString("parent has invalid address");
+  return false;
+}
+
+ProcessSP process_sp = GetProcessSP();
+if (!process_sp) {
+  m_error.SetErrorString("no process");
+  return false;
+}
+
+TargetSP target_sp = GetTargetSP();
+if (!target_sp) {
+  m_error.SetErrorString("no target");
+  return false;
+}
+
+// Each `vtable_entry_addr` points to the function pointer.
+addr_t vtable_entry_addr = parent_addr + m_func_idx * m_addr_size;
+addr_t vfunc_ptr =
+process_sp->ReadPointerFromMemory(vtable_entry_addr, m_error);
+if (m_error.Fail()) {
+  m_error.SetErrorStringWithFormat(
+  "failed to read virtual function entry 0x%16.16" PRIx64,
+  vtable_entry_addr);
+  return false;
+}
+
+
+// Set our value to be the load address of the function pointer in memory
+// and our type to be the function pointer type.
+m_value.SetValueType(Value::ValueType::LoadAddress);
+m_value.GetScalar() = vtable_entry_addr;
+
+// See if our resolved address points to a function in the debug info. If
+// it does, then we can report the type as a function prototype for this
+// function.
+Function *function = nullptr;
+Address resolved_vfunc_ptr_address;
+target_sp->ResolveLoadAddress(vfunc_ptr, resolved_vfunc_ptr_address);
+if (resolved_vfunc_ptr_address.IsValid())
+  function = resolved_vfunc_ptr_address.CalculateSymbolContextFunction();
+if (function) {
+  m_value.SetCompilerType(function->GetCompilerType().GetPointerType());
+} else {
+  // Set our value's compiler type to a generic function protoype so that
+  // it displays as a hex function pointer for the value and the summary
+  // will display the address description.
+
+  // Get the original type that this vtable is based off of so we can get
+  // the language from it correctly.
+  ValueObject *val = parent->GetParent();
+  auto type_system = target_sp->GetScratchTypeSystemForLanguage(
+val ? val->GetObjectRuntimeLanguage() : eLanguageTypeC_plus_plus);
+  if (type_system) {
+m_value.SetCompilerType(
+(*type_system)->CreateGenericFunctionPrototype().GetPointerType());
+  } else {
+consumeError(type_system.takeError());
+  }
+}
+
+// Now read our value into m_data so that our we can use the default
+// summary provider for C++ for function pointers which will get the
+// address description for our function pointer.
+if (m_error.Success()) {
+  const bool thread_and_frame_only_if_stopped = true;
+  ExecutionContext exe_ctx(
+GetExecutionContextRef().Lock(thread_and_frame_only_if_stopped));
+  m_error = m_value.GetValueAsData(&exe_ctx, m_data, GetModule().get());
+}
+SetValueDidChange(true);
+SetValueIsValid(true);
+return true;
+  };
+
+  CompilerType GetCompilerTypeImpl() override {
+return m_value.GetCompilerType();
+  };
+
+  const 

[Lldb-commits] [lldb] Add the ability to get a C++ vtable ValueObject from another ValueObj… (PR #67599)

2023-09-28 Thread Greg Clayton via lldb-commits


@@ -54,134 +54,182 @@ bool 
ItaniumABILanguageRuntime::CouldHaveDynamicValue(ValueObject &in_value) {
   check_objc);
 }
 
-TypeAndOrName ItaniumABILanguageRuntime::GetTypeInfoFromVTableAddress(
-ValueObject &in_value, lldb::addr_t original_ptr,
-lldb::addr_t vtable_load_addr) {
-  if (m_process && vtable_load_addr != LLDB_INVALID_ADDRESS) {
-// Find the symbol that contains the "vtable_load_addr" address
-Address vtable_addr;
-Target &target = m_process->GetTarget();
-if (!target.GetSectionLoadList().IsEmpty()) {
-  if (target.GetSectionLoadList().ResolveLoadAddress(vtable_load_addr,
- vtable_addr)) {
-// See if we have cached info for this type already
-TypeAndOrName type_info = GetDynamicTypeInfo(vtable_addr);
-if (type_info)
-  return type_info;
-
-SymbolContext sc;
-target.GetImages().ResolveSymbolContextForAddress(
-vtable_addr, eSymbolContextSymbol, sc);
-Symbol *symbol = sc.symbol;
-if (symbol != nullptr) {
-  const char *name =
-  symbol->GetMangled().GetDemangledName().AsCString();
-  if (name && strstr(name, vtable_demangled_prefix) == name) {
-Log *log = GetLog(LLDBLog::Object);
-LLDB_LOGF(log,
-  "0x%16.16" PRIx64
-  ": static-type = '%s' has vtable symbol '%s'\n",
-  original_ptr, in_value.GetTypeName().GetCString(), name);
-// We are a C++ class, that's good.  Get the class name and look it
-// up:
-const char *class_name = name + strlen(vtable_demangled_prefix);
-// We know the class name is absolute, so tell FindTypes that by
-// prefixing it with the root namespace:
-std::string lookup_name("::");
-lookup_name.append(class_name);
-
-type_info.SetName(class_name);
-const bool exact_match = true;
-TypeList class_types;
-
-// First look in the module that the vtable symbol came from and
-// look for a single exact match.
-llvm::DenseSet searched_symbol_files;
-if (sc.module_sp)
-  sc.module_sp->FindTypes(ConstString(lookup_name), exact_match, 1,
+TypeAndOrName ItaniumABILanguageRuntime::GetTypeInfo(
+ValueObject &in_value, const VTableInfo &vtable_info) {
+  if (vtable_info.addr.IsSectionOffset()) {
+// See if we have cached info for this type already
+TypeAndOrName type_info = GetDynamicTypeInfo(vtable_info.addr);
+if (type_info)
+  return type_info;
+
+if (vtable_info.symbol) {
+  Log *log = GetLog(LLDBLog::Object);
+  llvm::StringRef symbol_name =
+  vtable_info.symbol->GetMangled().GetDemangledName().GetStringRef();
+  LLDB_LOGF(log,
+"0x%16.16" PRIx64
+": static-type = '%s' has vtable symbol '%s'\n",
+in_value.GetPointerValue(),
+in_value.GetTypeName().GetCString(),
+symbol_name.str().c_str());
+  // We are a C++ class, that's good.  Get the class name and look it
+  // up:
+  llvm::StringRef class_name = symbol_name;
+  class_name.consume_front(vtable_demangled_prefix);
+  // We know the class name is absolute, so tell FindTypes that by
+  // prefixing it with the root namespace:
+  std::string lookup_name("::");
+  lookup_name.append(class_name.data(), class_name.size());
+
+  type_info.SetName(class_name);
+  const bool exact_match = true;
+  TypeList class_types;
+
+  // First look in the module that the vtable symbol came from and
+  // look for a single exact match.
+  llvm::DenseSet searched_symbol_files;
+  ModuleSP module_sp = vtable_info.symbol->CalculateSymbolContextModule();
+  if (module_sp)
+module_sp->FindTypes(ConstString(lookup_name), exact_match, 1,
+  searched_symbol_files, class_types);
+
+  // If we didn't find a symbol, then move on to the entire module
+  // list in the target and get as many unique matches as possible
+  Target &target = m_process->GetTarget();
+  if (class_types.Empty())
+target.GetImages().FindTypes(nullptr, ConstString(lookup_name),
+  exact_match, UINT32_MAX,
   searched_symbol_files, class_types);
 
-// If we didn't find a symbol, then move on to the entire module
-// list in the target and get as many unique matches as possible
-if (class_types.Empty())
-  target.GetImages().FindTypes(nullptr, ConstString(lookup_name),
-   exact_match, UINT32_MAX,
-   searched_symbol_files,

[Lldb-commits] [lldb] [lldb][FreeBSD] Add dynamic loader handle class for FreeBSD Kernel (PR #67106)

2023-09-28 Thread Ed Maste via lldb-commits

emaste wrote:

> I will let other FreeBSD folks do the final approval since I don't work on 
> FreeBSD.

@clayborg this change LGTM for FreeBSD. I'm still not fully sorted on the 
approach for landing the commits post transition to GitHub. Also see the 
comment about author name above.


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


[Lldb-commits] [lldb] Add the ability to get a C++ vtable ValueObject from another ValueObj… (PR #67599)

2023-09-28 Thread via lldb-commits


@@ -54,134 +54,182 @@ bool 
ItaniumABILanguageRuntime::CouldHaveDynamicValue(ValueObject &in_value) {
   check_objc);
 }
 
-TypeAndOrName ItaniumABILanguageRuntime::GetTypeInfoFromVTableAddress(
-ValueObject &in_value, lldb::addr_t original_ptr,
-lldb::addr_t vtable_load_addr) {
-  if (m_process && vtable_load_addr != LLDB_INVALID_ADDRESS) {
-// Find the symbol that contains the "vtable_load_addr" address
-Address vtable_addr;
-Target &target = m_process->GetTarget();
-if (!target.GetSectionLoadList().IsEmpty()) {
-  if (target.GetSectionLoadList().ResolveLoadAddress(vtable_load_addr,
- vtable_addr)) {
-// See if we have cached info for this type already
-TypeAndOrName type_info = GetDynamicTypeInfo(vtable_addr);
-if (type_info)
-  return type_info;
-
-SymbolContext sc;
-target.GetImages().ResolveSymbolContextForAddress(
-vtable_addr, eSymbolContextSymbol, sc);
-Symbol *symbol = sc.symbol;
-if (symbol != nullptr) {
-  const char *name =
-  symbol->GetMangled().GetDemangledName().AsCString();
-  if (name && strstr(name, vtable_demangled_prefix) == name) {
-Log *log = GetLog(LLDBLog::Object);
-LLDB_LOGF(log,
-  "0x%16.16" PRIx64
-  ": static-type = '%s' has vtable symbol '%s'\n",
-  original_ptr, in_value.GetTypeName().GetCString(), name);
-// We are a C++ class, that's good.  Get the class name and look it
-// up:
-const char *class_name = name + strlen(vtable_demangled_prefix);
-// We know the class name is absolute, so tell FindTypes that by
-// prefixing it with the root namespace:
-std::string lookup_name("::");
-lookup_name.append(class_name);
-
-type_info.SetName(class_name);
-const bool exact_match = true;
-TypeList class_types;
-
-// First look in the module that the vtable symbol came from and
-// look for a single exact match.
-llvm::DenseSet searched_symbol_files;
-if (sc.module_sp)
-  sc.module_sp->FindTypes(ConstString(lookup_name), exact_match, 1,
+TypeAndOrName ItaniumABILanguageRuntime::GetTypeInfo(
+ValueObject &in_value, const VTableInfo &vtable_info) {
+  if (vtable_info.addr.IsSectionOffset()) {
+// See if we have cached info for this type already
+TypeAndOrName type_info = GetDynamicTypeInfo(vtable_info.addr);
+if (type_info)
+  return type_info;
+
+if (vtable_info.symbol) {
+  Log *log = GetLog(LLDBLog::Object);
+  llvm::StringRef symbol_name =
+  vtable_info.symbol->GetMangled().GetDemangledName().GetStringRef();
+  LLDB_LOGF(log,
+"0x%16.16" PRIx64
+": static-type = '%s' has vtable symbol '%s'\n",
+in_value.GetPointerValue(),
+in_value.GetTypeName().GetCString(),
+symbol_name.str().c_str());
+  // We are a C++ class, that's good.  Get the class name and look it
+  // up:
+  llvm::StringRef class_name = symbol_name;
+  class_name.consume_front(vtable_demangled_prefix);
+  // We know the class name is absolute, so tell FindTypes that by
+  // prefixing it with the root namespace:
+  std::string lookup_name("::");
+  lookup_name.append(class_name.data(), class_name.size());
+
+  type_info.SetName(class_name);
+  const bool exact_match = true;
+  TypeList class_types;
+
+  // First look in the module that the vtable symbol came from and
+  // look for a single exact match.
+  llvm::DenseSet searched_symbol_files;
+  ModuleSP module_sp = vtable_info.symbol->CalculateSymbolContextModule();
+  if (module_sp)
+module_sp->FindTypes(ConstString(lookup_name), exact_match, 1,
+  searched_symbol_files, class_types);
+
+  // If we didn't find a symbol, then move on to the entire module
+  // list in the target and get as many unique matches as possible
+  Target &target = m_process->GetTarget();
+  if (class_types.Empty())
+target.GetImages().FindTypes(nullptr, ConstString(lookup_name),
+  exact_match, UINT32_MAX,
   searched_symbol_files, class_types);
 
-// If we didn't find a symbol, then move on to the entire module
-// list in the target and get as many unique matches as possible
-if (class_types.Empty())
-  target.GetImages().FindTypes(nullptr, ConstString(lookup_name),
-   exact_match, UINT32_MAX,
-   searched_symbol_files,

[Lldb-commits] [lldb] [lldb][FreeBSD] Add dynamic loader handle class for FreeBSD Kernel (PR #67106)

2023-09-28 Thread Greg Clayton via lldb-commits

clayborg wrote:

> > I will let other FreeBSD folks do the final approval since I don't work on 
> > FreeBSD.
> 
> @clayborg this change LGTM for FreeBSD. I'm still not fully sorted on the 
> approach for landing the commits post transition to GitHub. Also see the 
> comment about author name above.

There is a web page that covers the new submission process: 
https://llvm.org/docs/GitHub.html

I haven't done it yet either



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


[Lldb-commits] [lldb] [lldb][FreeBSD] Add dynamic loader handle class for FreeBSD Kernel (PR #67106)

2023-09-28 Thread Greg Clayton via lldb-commits

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


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


[Lldb-commits] [lldb] [libc++] Implement ranges::contains_subrange (PR #66963)

2023-09-28 Thread via lldb-commits


@@ -0,0 +1,145 @@
+//===--===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+
+#ifndef _LIBCPP___ALGORITHM_RANGES_CONTAINS_SUBRANGE_H
+#define _LIBCPP___ALGORITHM_RANGES_CONTAINS_SUBRANGE_H
+
+#include <__algorithm/ranges_starts_with.h>
+#include <__config>
+#include <__functional/identity.h>
+#include <__functional/ranges_operations.h>
+#include <__functional/reference_wrapper.h>
+#include <__iterator/concepts.h>
+#include <__iterator/distance.h>
+#include <__iterator/indirectly_comparable.h>
+#include <__iterator/projected.h>
+#include <__ranges/access.h>
+#include <__ranges/concepts.h>
+#include <__utility/move.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+#if _LIBCPP_STD_VER >= 23
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+namespace ranges {
+namespace __contains_subrange {
+struct __fn {
+  template  _Sent1,
+input_iterator _Iter2,
+sentinel_for<_Iter2> _Sent2,
+class _Pred,
+class _Proj1,
+class _Proj2,
+class _Offset>
+  static _LIBCPP_HIDE_FROM_ABI constexpr bool __contains_subrange_fn_impl(
+  _Iter1 __first1,
+  _Sent1 __last1,
+  _Iter2 __first2,
+  _Sent2 __last2,
+  _Pred& __pred,
+  _Proj1& __proj1,
+  _Proj2& __proj2,
+  _Offset __offset) {
+if (__offset < 0)
+  return false;
+else {
+  for (; __offset >= 0; __offset--, __first1++) {
+auto result = ranges::starts_with(
+std::move(__first1),
+std::move(__last1),
+std::move(__first2),
+std::move(__last2),
+std::ref(__pred),
+std::ref(__proj1),
+std::ref(__proj2));
+if (result)
+  return true;
+  }
+  return false;
+}

ZijunZhaoCCK wrote:

Yes.
Initially, I didn't aware that I can use `ranges::search`.
Then I tried to replace `ranges::starts_with` with `ranges::search` and I got 

> constraints not satisfied for class template 'subrange' [with _Iter = 
> cpp20_input_iterator, _Sent = cpp20_input_iterator, _Kind = 
> std::ranges::subrange_kind::unsized]

error in the test file.

I tried to test with forward iterator. It works well.



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


[Lldb-commits] [lldb] [lldb][FreeBSD] Add dynamic loader handle class for FreeBSD Kernel (PR #67106)

2023-09-28 Thread Ed Maste via lldb-commits

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


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


[Lldb-commits] [lldb] [lldb][FreeBSD] Add dynamic loader handle class for FreeBSD Kernel (PR #67106)

2023-09-28 Thread Ed Maste via lldb-commits

emaste wrote:

https://llvm.org/docs/GitHub.html#landing-your-change

> There are two different ways to do this:
>
> - [Interactive rebase](https://git-scm.com/docs/git-rebase#_interactive_mode) 
> with fixup’s. This is the recommended method since you can control the final 
> commit message and inspect that the final commit looks as you expect. When 
> your local state is correct, remember to force-push to your branch and press 
> the merge button afterwards.
>
> - Use the button Squash and merge in GitHub’s web interface, if you do this 
> remember to review the commit message when prompted.

So I suspect the best way to go here is @aokblast locally squashes these 
commits into one, updates author if desired, fixes up commit messages if 
necessary, and then force-pushes to this pull request. Then @clayborg or I push 
the merge button.

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


[Lldb-commits] [lldb] Add the ability to get a C++ vtable ValueObject from another ValueObj… (PR #67599)

2023-09-28 Thread Greg Clayton via lldb-commits

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

>From 8fa9aae354ac455f4ea443de1bb5f753fe93fb51 Mon Sep 17 00:00:00 2001
From: Greg Clayton 
Date: Wed, 27 Sep 2023 13:03:40 -0700
Subject: [PATCH 1/4] Add the ability to get a C++ vtable ValueObject from
 another ValueObject.

This patch adds the ability to ask a ValueObject for a ValueObject that 
represents the virtual function table for a C++ class. If the ValueObject is 
not a C++ class with a vtable, a valid ValueObject value will be returned that 
contains an appropriate error. If it is successful a valid ValueObject that 
represents vtable will be returned. The ValueObject that is returned will have 
a name that matches the demangled value for a C++ vtable mangled name like 
"vtable for ". It will have N children, one for each virtual 
function pointer. Each child's value is the function pointer itself, the 
summary is the symbolication of this function pointer, and the type will be a 
valid function pointer from the debug info if there is debug information 
corresponding to the virtual function pointer.

The vtable SBValue will have the following:
- SBValue::GetName() returns "vtable for "
- SBValue::GetValue() returns a string representation of the vtable address
- SBValue::GetSummary() returns NULL
- SBValue::GetType() returns a type appropriate for a uintptr_t type for the 
current process
- SBValue::GetLoadAddress() returns the address of the vtable adderess
- SBValue::GetValueAsUnsigned(...) returns the vtable address
- SBValue::GetNumChildren() returns the number of virtual function pointers in 
the vtable
- SBValue::GetChildAtIndex(...) returns a SBValue that represents a virtual 
function pointer

The child SBValue objects that represent a virtual function pointer has the 
following values:
- SBValue::GetName() returns "[%u]" where %u is the vtable function pointer 
index
- SBValue::GetValue() returns a string representation of the virtual function 
pointer
- SBValue::GetSummary() returns a symbolicated respresentation of the virtual 
function pointer
- SBValue::GetType() returns the function prototype type if there is debug 
info, or a generic funtion prototype if there is no debug info
- SBValue::GetLoadAddress() returns the address of the virtual function pointer
- SBValue::GetValueAsUnsigned(...) returns the virtual function pointer
- SBValue::GetNumChildren() returns 0
- SBValue::GetChildAtIndex(...) returns invalid SBValue for any index

Examples of using this API via python:

```
(lldb) script vtable = lldb.frame.FindVariable("shape_ptr").GetVTable()
(lldb) script vtable
vtable for Shape = 0x00014088 {
  [0] = 0x00013d20 a.out`Shape::~Shape() at main.cpp:3
  [1] = 0x00013e4c a.out`Shape::~Shape() at main.cpp:3
  [2] = 0x00013e7c a.out`Shape::area() at main.cpp:4
  [3] = 0x00013e3c a.out`Shape::optional() at main.cpp:7
}
(lldb) script c = vtable.GetChildAtIndex(0)
(lldb) script c
(void ()) [0] = 0x00013d20 a.out`Shape::~Shape() at main.cpp:3
```
---
 lldb/include/lldb/API/SBValue.h   |  28 ++
 lldb/include/lldb/Core/ValueObject.h  |   4 +
 lldb/include/lldb/Core/ValueObjectChild.h |   1 +
 lldb/include/lldb/Core/ValueObjectVTable.h|  65 
 lldb/include/lldb/Symbol/TypeSystem.h |   4 +
 lldb/include/lldb/lldb-enumerations.h |   4 +-
 lldb/source/API/SBValue.cpp   |  17 +-
 lldb/source/Commands/CommandObjectFrame.cpp   |   2 +
 lldb/source/Core/CMakeLists.txt   |   1 +
 lldb/source/Core/ValueObject.cpp  |   5 +
 lldb/source/Core/ValueObjectVTable.cpp| 325 ++
 .../DataFormatters/CXXFunctionPointer.cpp |   6 +-
 .../Language/CPlusPlus/CPlusPlusLanguage.cpp  |   4 +-
 .../TypeSystem/Clang/TypeSystemClang.cpp  |  26 +-
 .../TypeSystem/Clang/TypeSystemClang.h|   4 +
 lldb/test/API/functionalities/vtable/Makefile |   3 +
 .../functionalities/vtable/TestVTableValue.py | 135 
 lldb/test/API/functionalities/vtable/main.cpp |  37 ++
 18 files changed, 664 insertions(+), 7 deletions(-)
 create mode 100644 lldb/include/lldb/Core/ValueObjectVTable.h
 create mode 100644 lldb/source/Core/ValueObjectVTable.cpp
 create mode 100644 lldb/test/API/functionalities/vtable/Makefile
 create mode 100644 lldb/test/API/functionalities/vtable/TestVTableValue.py
 create mode 100644 lldb/test/API/functionalities/vtable/main.cpp

diff --git a/lldb/include/lldb/API/SBValue.h b/lldb/include/lldb/API/SBValue.h
index b66c2d5642b6f95..333bdf1738eecaf 100644
--- a/lldb/include/lldb/API/SBValue.h
+++ b/lldb/include/lldb/API/SBValue.h
@@ -374,6 +374,34 @@ class LLDB_API SBValue {
   lldb::SBWatchpoint WatchPointee(bool resolve_location, bool read, bool write,
   SBError &error);
 
+  /// If this value represents a C++ class that has a vtable, return an value
+  /// that represents the virtual function table.
+  ///
+  /// SBValu

[Lldb-commits] [lldb] [lldb][FreeBSD] Add dynamic loader handle class for FreeBSD Kernel (PR #67106)

2023-09-28 Thread Ed Maste via lldb-commits

emaste wrote:

Oh, I think we should also mention GSoC in the commit message. Something like 
`This project was part of FreeBSD's participation in Google Summer of Code 
2023.` or so.

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


[Lldb-commits] [lldb] Add the ability to get a C++ vtable ValueObject from another ValueObj… (PR #67599)

2023-09-28 Thread via lldb-commits


@@ -0,0 +1,325 @@
+//===-- ValueObjectVTable.cpp 
-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+
+#include "lldb/Core/ValueObjectVTable.h"
+#include "lldb/Core/Module.h"
+#include "lldb/Core/ValueObjectChild.h"
+#include "lldb/Symbol/Function.h"
+#include "lldb/lldb-defines.h"
+#include "lldb/lldb-enumerations.h"
+#include "lldb/lldb-forward.h"
+#include "lldb/lldb-private-enumerations.h"
+#include "clang/Tooling/Transformer/RangeSelector.h"
+#include "llvm/Support/MathExtras.h"
+#include 
+
+using namespace lldb;
+using namespace lldb_private;
+
+class ValueObjectVTableChild : public ValueObject {
+public:
+  ValueObjectVTableChild(ValueObject &parent, uint32_t func_idx,
+ uint64_t addr_size)
+  : ValueObject(parent), m_func_idx(func_idx), m_addr_size(addr_size) {
+SetFormat(eFormatPointer);
+SetName(ConstString(llvm::formatv("[{0}]", func_idx).str()));
+  }
+
+  ~ValueObjectVTableChild() override = default;
+
+  std::optional GetByteSize() override { return m_addr_size; };
+
+  size_t CalculateNumChildren(uint32_t max) override { return 0; };
+
+  ValueType GetValueType() const override { return eValueTypeVTableEntry; };
+
+  bool IsInScope() override {
+ValueObject *parent = GetParent();
+if (parent)
+  return parent->IsInScope();
+return false;
+  };
+
+protected:
+  bool UpdateValue() override {
+SetValueIsValid(false);
+m_value.Clear();
+ValueObject *parent = GetParent();
+if (!parent) {
+  m_error.SetErrorString("no parent object");
+  return false;
+}
+
+addr_t parent_addr = parent->GetValueAsUnsigned(LLDB_INVALID_ADDRESS);
+if (parent_addr == LLDB_INVALID_ADDRESS) {
+  m_error.SetErrorString("parent has invalid address");

jeffreytan81 wrote:

This is public facing error right? Maybe be clear what is "parent" in this 
context. Like `can't get parent vtable address`. 

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


[Lldb-commits] [lldb] Add the ability to get a C++ vtable ValueObject from another ValueObj… (PR #67599)

2023-09-28 Thread via lldb-commits


@@ -0,0 +1,325 @@
+//===-- ValueObjectVTable.cpp 
-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+
+#include "lldb/Core/ValueObjectVTable.h"
+#include "lldb/Core/Module.h"
+#include "lldb/Core/ValueObjectChild.h"
+#include "lldb/Symbol/Function.h"
+#include "lldb/lldb-defines.h"
+#include "lldb/lldb-enumerations.h"
+#include "lldb/lldb-forward.h"
+#include "lldb/lldb-private-enumerations.h"
+#include "clang/Tooling/Transformer/RangeSelector.h"
+#include "llvm/Support/MathExtras.h"
+#include 
+
+using namespace lldb;
+using namespace lldb_private;
+
+class ValueObjectVTableChild : public ValueObject {
+public:
+  ValueObjectVTableChild(ValueObject &parent, uint32_t func_idx,
+ uint64_t addr_size)
+  : ValueObject(parent), m_func_idx(func_idx), m_addr_size(addr_size) {
+SetFormat(eFormatPointer);
+SetName(ConstString(llvm::formatv("[{0}]", func_idx).str()));
+  }
+
+  ~ValueObjectVTableChild() override = default;
+
+  std::optional GetByteSize() override { return m_addr_size; };
+
+  size_t CalculateNumChildren(uint32_t max) override { return 0; };
+
+  ValueType GetValueType() const override { return eValueTypeVTableEntry; };
+
+  bool IsInScope() override {
+ValueObject *parent = GetParent();
+if (parent)
+  return parent->IsInScope();
+return false;
+  };
+
+protected:
+  bool UpdateValue() override {
+SetValueIsValid(false);
+m_value.Clear();
+ValueObject *parent = GetParent();
+if (!parent) {
+  m_error.SetErrorString("no parent object");
+  return false;
+}
+
+addr_t parent_addr = parent->GetValueAsUnsigned(LLDB_INVALID_ADDRESS);
+if (parent_addr == LLDB_INVALID_ADDRESS) {
+  m_error.SetErrorString("parent has invalid address");
+  return false;
+}
+
+ProcessSP process_sp = GetProcessSP();
+if (!process_sp) {
+  m_error.SetErrorString("no process");
+  return false;
+}
+
+TargetSP target_sp = GetTargetSP();
+if (!target_sp) {
+  m_error.SetErrorString("no target");
+  return false;
+}
+
+// Each `vtable_entry_addr` points to the function pointer.
+addr_t vtable_entry_addr = parent_addr + m_func_idx * m_addr_size;
+addr_t vfunc_ptr =
+process_sp->ReadPointerFromMemory(vtable_entry_addr, m_error);
+if (m_error.Fail()) {
+  m_error.SetErrorStringWithFormat(
+  "failed to read virtual function entry 0x%16.16" PRIx64,
+  vtable_entry_addr);
+  return false;
+}
+
+Address resolved_vfunc_ptr_address;
+target_sp->ResolveLoadAddress(vfunc_ptr, resolved_vfunc_ptr_address);
+if (!resolved_vfunc_ptr_address.IsValid()) {
+  m_error.SetErrorStringWithFormat(
+  "unable to resolve func ptr address: 0x%16.16" PRIx64, vfunc_ptr);
+  return false;
+}
+
+// Set our value to be the load address of the function pointer in memory
+// and our type to be the function pointer type.
+m_value.SetValueType(Value::ValueType::LoadAddress);
+m_value.GetScalar() = vtable_entry_addr;
+
+// See if our resolved address points to a function in the debug info. If
+// it does, then we can report the type as a function prototype for this
+// function.
+Function *function =
+resolved_vfunc_ptr_address.CalculateSymbolContextFunction();
+if (function) {
+  m_value.SetCompilerType(function->GetCompilerType());
+} else {
+  // Set our value's compiler type to a generic function protoype so that

jeffreytan81 wrote:

Like!

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


[Lldb-commits] [lldb] Add the ability to get a C++ vtable ValueObject from another ValueObj… (PR #67599)

2023-09-28 Thread via lldb-commits

https://github.com/jeffreytan81 commented:

Oops, I found my old comments from yesterday did not go out. Still need to 
learn the new UI. 

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


[Lldb-commits] [lldb] Add the ability to get a C++ vtable ValueObject from another ValueObj… (PR #67599)

2023-09-28 Thread via lldb-commits


@@ -0,0 +1,325 @@
+//===-- ValueObjectVTable.cpp 
-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+
+#include "lldb/Core/ValueObjectVTable.h"
+#include "lldb/Core/Module.h"
+#include "lldb/Core/ValueObjectChild.h"
+#include "lldb/Symbol/Function.h"
+#include "lldb/lldb-defines.h"
+#include "lldb/lldb-enumerations.h"
+#include "lldb/lldb-forward.h"
+#include "lldb/lldb-private-enumerations.h"
+#include "clang/Tooling/Transformer/RangeSelector.h"
+#include "llvm/Support/MathExtras.h"
+#include 
+
+using namespace lldb;
+using namespace lldb_private;
+
+class ValueObjectVTableChild : public ValueObject {
+public:
+  ValueObjectVTableChild(ValueObject &parent, uint32_t func_idx,
+ uint64_t addr_size)
+  : ValueObject(parent), m_func_idx(func_idx), m_addr_size(addr_size) {
+SetFormat(eFormatPointer);
+SetName(ConstString(llvm::formatv("[{0}]", func_idx).str()));
+  }
+
+  ~ValueObjectVTableChild() override = default;
+
+  std::optional GetByteSize() override { return m_addr_size; };
+
+  size_t CalculateNumChildren(uint32_t max) override { return 0; };
+
+  ValueType GetValueType() const override { return eValueTypeVTableEntry; };
+
+  bool IsInScope() override {
+ValueObject *parent = GetParent();
+if (parent)
+  return parent->IsInScope();
+return false;
+  };
+
+protected:
+  bool UpdateValue() override {
+SetValueIsValid(false);
+m_value.Clear();
+ValueObject *parent = GetParent();
+if (!parent) {
+  m_error.SetErrorString("no parent object");
+  return false;
+}
+
+addr_t parent_addr = parent->GetValueAsUnsigned(LLDB_INVALID_ADDRESS);
+if (parent_addr == LLDB_INVALID_ADDRESS) {
+  m_error.SetErrorString("parent has invalid address");
+  return false;
+}
+
+ProcessSP process_sp = GetProcessSP();
+if (!process_sp) {
+  m_error.SetErrorString("no process");
+  return false;
+}
+
+TargetSP target_sp = GetTargetSP();
+if (!target_sp) {
+  m_error.SetErrorString("no target");
+  return false;
+}
+
+// Each `vtable_entry_addr` points to the function pointer.
+addr_t vtable_entry_addr = parent_addr + m_func_idx * m_addr_size;
+addr_t vfunc_ptr =
+process_sp->ReadPointerFromMemory(vtable_entry_addr, m_error);
+if (m_error.Fail()) {
+  m_error.SetErrorStringWithFormat(
+  "failed to read virtual function entry 0x%16.16" PRIx64,
+  vtable_entry_addr);
+  return false;
+}
+
+Address resolved_vfunc_ptr_address;
+target_sp->ResolveLoadAddress(vfunc_ptr, resolved_vfunc_ptr_address);
+if (!resolved_vfunc_ptr_address.IsValid()) {
+  m_error.SetErrorStringWithFormat(
+  "unable to resolve func ptr address: 0x%16.16" PRIx64, vfunc_ptr);
+  return false;
+}
+
+// Set our value to be the load address of the function pointer in memory
+// and our type to be the function pointer type.
+m_value.SetValueType(Value::ValueType::LoadAddress);
+m_value.GetScalar() = vtable_entry_addr;
+
+// See if our resolved address points to a function in the debug info. If
+// it does, then we can report the type as a function prototype for this
+// function.
+Function *function =
+resolved_vfunc_ptr_address.CalculateSymbolContextFunction();
+if (function) {
+  m_value.SetCompilerType(function->GetCompilerType());
+} else {
+  // Set our value's compiler type to a generic function protoype so that
+  // it displays as a hex function pointer for the value and the summary
+  // will display the address description.
+  auto type_system_or_err =
+target_sp->GetScratchTypeSystemForLanguage(eLanguageTypeC_plus_plus);
+  if (type_system_or_err) {
+CompilerType proto = 
(*type_system_or_err)->CreateGenericFunctionPrototype();
+if (proto.IsFunctionType())
+  m_value.SetCompilerType(proto);
+  } else {
+consumeError(type_system_or_err.takeError());
+  }
+}
+
+// Now read our value into m_data so that our we can use the default
+// summary provider for C++ for function pointers which will get the
+// address description for our function pointer.
+if (m_error.Success()) {
+  const bool thread_and_frame_only_if_stopped = true;
+  ExecutionContext exe_ctx(
+GetExecutionContextRef().Lock(thread_and_frame_only_if_stopped));
+  m_error = m_value.GetValueAsData(&exe_ctx, m_data, GetModule().get());
+}
+SetValueDidChange(true);
+SetValueIsValid(true);
+return true;
+  };
+
+  CompilerType GetCompilerTypeImpl() override {
+return m_value.GetCompilerType();
+  }

[Lldb-commits] [lldb] Add the ability to get a C++ vtable ValueObject from another ValueObj… (PR #67599)

2023-09-28 Thread via lldb-commits

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


[Lldb-commits] [lldb] Add the ability to get a C++ vtable ValueObject from another ValueObj… (PR #67599)

2023-09-28 Thread via lldb-commits

jeffreytan81 wrote:

> > * Can we test this during multiple inheritance? Should we print multiple 
> > vtables?
>  [Greg] I can add a test for this and make sure things works when dynamic 
> typing is on and off. We won't print multiple vtables, as each class has only 
> 1 vtable, it will just include all of the virtual methods needed for any 
> inherited classes.

I remember some compiler's multi-inheritance implementation is putting one 
vtable_ptr in object for each parent class. Maybe not in clang? 

> > * Test in coredump to make sure it works
>   [Greg] That is tricky due to the vtables never being stored in the core 
> files since they are in read only sections.

Right, I am not asking for a testcase, but manual testing. 



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


[Lldb-commits] [lldb] [lldb][FreeBSD] Add dynamic loader handle class for FreeBSD Kernel (PR #67106)

2023-09-28 Thread via lldb-commits

aokblast wrote:

As my mentor Li-Wen Hsu suggest, It is better to separate this patch into two 
commits. One for DynamicLoaderFreeBSDKernel class, and another for the 
modification about ObjectFile.cpp. Should I use 1 commits to include both of 
these change or separate it as two?

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


[Lldb-commits] [lldb] [lldb][FreeBSD] Add dynamic loader handle class for FreeBSD Kernel (PR #67106)

2023-09-28 Thread Greg Clayton via lldb-commits

clayborg wrote:

> As my mentor Li-Wen Hsu suggest, It is better to separate this patch into two 
> commits. One for DynamicLoaderFreeBSDKernel class, and another for the 
> modification about ObjectFile.cpp. Should I use 1 commits to include both of 
> these change or separate it as two?

I am ok with it being one patch since it is related to implementing kernel 
debugging.

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


[Lldb-commits] [lldb] Add the ability to get a C++ vtable ValueObject from another ValueObj… (PR #67599)

2023-09-28 Thread Greg Clayton via lldb-commits


@@ -0,0 +1,325 @@
+//===-- ValueObjectVTable.cpp 
-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+
+#include "lldb/Core/ValueObjectVTable.h"
+#include "lldb/Core/Module.h"
+#include "lldb/Core/ValueObjectChild.h"
+#include "lldb/Symbol/Function.h"
+#include "lldb/lldb-defines.h"
+#include "lldb/lldb-enumerations.h"
+#include "lldb/lldb-forward.h"
+#include "lldb/lldb-private-enumerations.h"
+#include "clang/Tooling/Transformer/RangeSelector.h"
+#include "llvm/Support/MathExtras.h"
+#include 
+
+using namespace lldb;
+using namespace lldb_private;
+
+class ValueObjectVTableChild : public ValueObject {
+public:
+  ValueObjectVTableChild(ValueObject &parent, uint32_t func_idx,
+ uint64_t addr_size)
+  : ValueObject(parent), m_func_idx(func_idx), m_addr_size(addr_size) {
+SetFormat(eFormatPointer);
+SetName(ConstString(llvm::formatv("[{0}]", func_idx).str()));
+  }
+
+  ~ValueObjectVTableChild() override = default;
+
+  std::optional GetByteSize() override { return m_addr_size; };
+
+  size_t CalculateNumChildren(uint32_t max) override { return 0; };
+
+  ValueType GetValueType() const override { return eValueTypeVTableEntry; };
+
+  bool IsInScope() override {
+ValueObject *parent = GetParent();
+if (parent)
+  return parent->IsInScope();
+return false;
+  };
+
+protected:
+  bool UpdateValue() override {
+SetValueIsValid(false);
+m_value.Clear();
+ValueObject *parent = GetParent();
+if (!parent) {
+  m_error.SetErrorString("no parent object");
+  return false;
+}
+
+addr_t parent_addr = parent->GetValueAsUnsigned(LLDB_INVALID_ADDRESS);
+if (parent_addr == LLDB_INVALID_ADDRESS) {
+  m_error.SetErrorString("parent has invalid address");
+  return false;
+}
+
+ProcessSP process_sp = GetProcessSP();
+if (!process_sp) {
+  m_error.SetErrorString("no process");
+  return false;
+}
+
+TargetSP target_sp = GetTargetSP();
+if (!target_sp) {
+  m_error.SetErrorString("no target");
+  return false;
+}
+
+// Each `vtable_entry_addr` points to the function pointer.
+addr_t vtable_entry_addr = parent_addr + m_func_idx * m_addr_size;
+addr_t vfunc_ptr =
+process_sp->ReadPointerFromMemory(vtable_entry_addr, m_error);
+if (m_error.Fail()) {
+  m_error.SetErrorStringWithFormat(
+  "failed to read virtual function entry 0x%16.16" PRIx64,
+  vtable_entry_addr);
+  return false;
+}
+
+Address resolved_vfunc_ptr_address;
+target_sp->ResolveLoadAddress(vfunc_ptr, resolved_vfunc_ptr_address);
+if (!resolved_vfunc_ptr_address.IsValid()) {
+  m_error.SetErrorStringWithFormat(
+  "unable to resolve func ptr address: 0x%16.16" PRIx64, vfunc_ptr);
+  return false;
+}
+
+// Set our value to be the load address of the function pointer in memory
+// and our type to be the function pointer type.
+m_value.SetValueType(Value::ValueType::LoadAddress);
+m_value.GetScalar() = vtable_entry_addr;
+
+// See if our resolved address points to a function in the debug info. If
+// it does, then we can report the type as a function prototype for this
+// function.
+Function *function =
+resolved_vfunc_ptr_address.CalculateSymbolContextFunction();
+if (function) {
+  m_value.SetCompilerType(function->GetCompilerType());
+} else {
+  // Set our value's compiler type to a generic function protoype so that
+  // it displays as a hex function pointer for the value and the summary
+  // will display the address description.
+  auto type_system_or_err =
+target_sp->GetScratchTypeSystemForLanguage(eLanguageTypeC_plus_plus);
+  if (type_system_or_err) {
+CompilerType proto = 
(*type_system_or_err)->CreateGenericFunctionPrototype();
+if (proto.IsFunctionType())
+  m_value.SetCompilerType(proto);
+  } else {
+consumeError(type_system_or_err.takeError());
+  }
+}
+
+// Now read our value into m_data so that our we can use the default
+// summary provider for C++ for function pointers which will get the
+// address description for our function pointer.
+if (m_error.Success()) {
+  const bool thread_and_frame_only_if_stopped = true;
+  ExecutionContext exe_ctx(
+GetExecutionContextRef().Lock(thread_and_frame_only_if_stopped));
+  m_error = m_value.GetValueAsData(&exe_ctx, m_data, GetModule().get());
+}
+SetValueDidChange(true);
+SetValueIsValid(true);
+return true;
+  };
+
+  CompilerType GetCompilerTypeImpl() override {
+return m_value.GetCompilerType();
+  }

[Lldb-commits] [lldb] Add the ability to get a C++ vtable ValueObject from another ValueObj… (PR #67599)

2023-09-28 Thread Greg Clayton via lldb-commits

clayborg wrote:





> > > * Can we test this during multiple inheritance? Should we print multiple 
> > > vtables?
> > >   [Greg] I can add a test for this and make sure things works when 
> > > dynamic typing is on and off. We won't print multiple vtables, as each 
> > > class has only 1 vtable, it will just include all of the virtual methods 
> > > needed for any inherited classes.
> 
> I remember some compiler's multi-inheritance implementation is putting one 
> vtable_ptr in object for each parent class. Maybe not in clang?

Each class has a single vtable and this table will contain a copy of all 
vtables that are needed for each class.



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


[Lldb-commits] [lldb] Add the ability to get a C++ vtable ValueObject from another ValueObj… (PR #67599)

2023-09-28 Thread Greg Clayton via lldb-commits

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

>From 8fa9aae354ac455f4ea443de1bb5f753fe93fb51 Mon Sep 17 00:00:00 2001
From: Greg Clayton 
Date: Wed, 27 Sep 2023 13:03:40 -0700
Subject: [PATCH 1/5] Add the ability to get a C++ vtable ValueObject from
 another ValueObject.

This patch adds the ability to ask a ValueObject for a ValueObject that 
represents the virtual function table for a C++ class. If the ValueObject is 
not a C++ class with a vtable, a valid ValueObject value will be returned that 
contains an appropriate error. If it is successful a valid ValueObject that 
represents vtable will be returned. The ValueObject that is returned will have 
a name that matches the demangled value for a C++ vtable mangled name like 
"vtable for ". It will have N children, one for each virtual 
function pointer. Each child's value is the function pointer itself, the 
summary is the symbolication of this function pointer, and the type will be a 
valid function pointer from the debug info if there is debug information 
corresponding to the virtual function pointer.

The vtable SBValue will have the following:
- SBValue::GetName() returns "vtable for "
- SBValue::GetValue() returns a string representation of the vtable address
- SBValue::GetSummary() returns NULL
- SBValue::GetType() returns a type appropriate for a uintptr_t type for the 
current process
- SBValue::GetLoadAddress() returns the address of the vtable adderess
- SBValue::GetValueAsUnsigned(...) returns the vtable address
- SBValue::GetNumChildren() returns the number of virtual function pointers in 
the vtable
- SBValue::GetChildAtIndex(...) returns a SBValue that represents a virtual 
function pointer

The child SBValue objects that represent a virtual function pointer has the 
following values:
- SBValue::GetName() returns "[%u]" where %u is the vtable function pointer 
index
- SBValue::GetValue() returns a string representation of the virtual function 
pointer
- SBValue::GetSummary() returns a symbolicated respresentation of the virtual 
function pointer
- SBValue::GetType() returns the function prototype type if there is debug 
info, or a generic funtion prototype if there is no debug info
- SBValue::GetLoadAddress() returns the address of the virtual function pointer
- SBValue::GetValueAsUnsigned(...) returns the virtual function pointer
- SBValue::GetNumChildren() returns 0
- SBValue::GetChildAtIndex(...) returns invalid SBValue for any index

Examples of using this API via python:

```
(lldb) script vtable = lldb.frame.FindVariable("shape_ptr").GetVTable()
(lldb) script vtable
vtable for Shape = 0x00014088 {
  [0] = 0x00013d20 a.out`Shape::~Shape() at main.cpp:3
  [1] = 0x00013e4c a.out`Shape::~Shape() at main.cpp:3
  [2] = 0x00013e7c a.out`Shape::area() at main.cpp:4
  [3] = 0x00013e3c a.out`Shape::optional() at main.cpp:7
}
(lldb) script c = vtable.GetChildAtIndex(0)
(lldb) script c
(void ()) [0] = 0x00013d20 a.out`Shape::~Shape() at main.cpp:3
```
---
 lldb/include/lldb/API/SBValue.h   |  28 ++
 lldb/include/lldb/Core/ValueObject.h  |   4 +
 lldb/include/lldb/Core/ValueObjectChild.h |   1 +
 lldb/include/lldb/Core/ValueObjectVTable.h|  65 
 lldb/include/lldb/Symbol/TypeSystem.h |   4 +
 lldb/include/lldb/lldb-enumerations.h |   4 +-
 lldb/source/API/SBValue.cpp   |  17 +-
 lldb/source/Commands/CommandObjectFrame.cpp   |   2 +
 lldb/source/Core/CMakeLists.txt   |   1 +
 lldb/source/Core/ValueObject.cpp  |   5 +
 lldb/source/Core/ValueObjectVTable.cpp| 325 ++
 .../DataFormatters/CXXFunctionPointer.cpp |   6 +-
 .../Language/CPlusPlus/CPlusPlusLanguage.cpp  |   4 +-
 .../TypeSystem/Clang/TypeSystemClang.cpp  |  26 +-
 .../TypeSystem/Clang/TypeSystemClang.h|   4 +
 lldb/test/API/functionalities/vtable/Makefile |   3 +
 .../functionalities/vtable/TestVTableValue.py | 135 
 lldb/test/API/functionalities/vtable/main.cpp |  37 ++
 18 files changed, 664 insertions(+), 7 deletions(-)
 create mode 100644 lldb/include/lldb/Core/ValueObjectVTable.h
 create mode 100644 lldb/source/Core/ValueObjectVTable.cpp
 create mode 100644 lldb/test/API/functionalities/vtable/Makefile
 create mode 100644 lldb/test/API/functionalities/vtable/TestVTableValue.py
 create mode 100644 lldb/test/API/functionalities/vtable/main.cpp

diff --git a/lldb/include/lldb/API/SBValue.h b/lldb/include/lldb/API/SBValue.h
index b66c2d5642b6f95..333bdf1738eecaf 100644
--- a/lldb/include/lldb/API/SBValue.h
+++ b/lldb/include/lldb/API/SBValue.h
@@ -374,6 +374,34 @@ class LLDB_API SBValue {
   lldb::SBWatchpoint WatchPointee(bool resolve_location, bool read, bool write,
   SBError &error);
 
+  /// If this value represents a C++ class that has a vtable, return an value
+  /// that represents the virtual function table.
+  ///
+  /// SBValu