[Lldb-commits] [PATCH] D139955: [LLDB] Change formatting to use llvm::formatv

2023-01-05 Thread Alexander Yermolovich via Phabricator via lldb-commits
ayermolo updated this revision to Diff 486719.
ayermolo added a comment.

removed +


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D139955/new/

https://reviews.llvm.org/D139955

Files:
  lldb/include/lldb/Core/Module.h
  lldb/include/lldb/Utility/Status.h
  lldb/source/Core/Module.cpp
  lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
  lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
  lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
  lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp
  lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp
  lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp
  lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.cpp
  lldb/source/Plugins/SymbolFile/DWARF/DWARFTypeUnit.cpp
  lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
  lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp
  lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
  lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp
  lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp
  lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp
  lldb/source/Symbol/CompileUnit.cpp
  lldb/source/Symbol/DWARFCallFrameInfo.cpp
  lldb/source/Target/SectionLoadList.cpp
  lldb/test/Shell/SymbolFile/DWARF/DW_AT_range-DW_FORM_sec_offset.s
  lldb/test/Shell/SymbolFile/DWARF/x86/debug_ranges-missing-section.s

Index: lldb/test/Shell/SymbolFile/DWARF/x86/debug_ranges-missing-section.s
===
--- lldb/test/Shell/SymbolFile/DWARF/x86/debug_ranges-missing-section.s
+++ lldb/test/Shell/SymbolFile/DWARF/x86/debug_ranges-missing-section.s
@@ -2,7 +2,7 @@
 # RUN: %lldb %t -o "image lookup -v -s lookup_ranges" -o exit 2>%t.error | FileCheck %s
 # RUN: cat %t.error | FileCheck %s --check-prefix ERROR
 
-# ERROR: DIE has DW_AT_ranges(DW_FORM_sec_offset 0x47) attribute, but range extraction failed (No debug_ranges section),
+# ERROR: DIE has DW_AT_ranges(DW_FORM_sec_offset 0x0047) attribute, but range extraction failed (No debug_ranges section),
 # CHECK:  Function: id = {0x001c}, name = "ranges", range = [0x-0x0004)
 # CHECK:Blocks: id = {0x001c}, range = [0x-0x0004)
 
Index: lldb/test/Shell/SymbolFile/DWARF/DW_AT_range-DW_FORM_sec_offset.s
===
--- lldb/test/Shell/SymbolFile/DWARF/DW_AT_range-DW_FORM_sec_offset.s
+++ lldb/test/Shell/SymbolFile/DWARF/DW_AT_range-DW_FORM_sec_offset.s
@@ -22,7 +22,7 @@
 # RUN: cat %t.error | FileCheck --check-prefix=ERROR %s
 
 # RNGLISTX-LABEL: image lookup -v -s lookup_rnglists
-# ERROR: error: {{.*}} {0x003f}: DIE has DW_AT_ranges(DW_FORM_rnglistx 0x0) attribute, but range extraction failed (DW_FORM_rnglistx cannot be used without DW_AT_rnglists_base for CU at 0x), please file a bug and attach the file at the start of this error message
+# ERROR: error: {{.*}} [0x003f]: DIE has DW_AT_ranges(DW_FORM_rnglistx 0x) attribute, but range extraction failed (DW_FORM_rnglistx cannot be used without DW_AT_rnglists_base for CU at 0x), please file a bug and attach the file at the start of this error message
 
 # RUN: llvm-mc -triple=x86_64-pc-linux -filetype=obj \
 # RUN:   --defsym RNGLISTX=0 --defsym RNGLISTBASE=0 %s > %t-rnglistbase
@@ -31,7 +31,7 @@
 # RUN: cat %t.error | FileCheck --check-prefix=ERRORBASE %s
 
 # RNGLISTBASE-LABEL: image lookup -v -s lookup_rnglists
-# ERRORBASE: error: {{.*}}-rnglistbase {0x0043}: DIE has DW_AT_ranges(DW_FORM_rnglistx 0x0) attribute, but range extraction failed (invalid range list table index 0; OffsetEntryCount is 0, DW_AT_rnglists_base is 24), please file a bug and attach the file at the start of this error message
+# ERRORBASE: error: {{.*}}-rnglistbase [0x0043]: DIE has DW_AT_ranges(DW_FORM_rnglistx 0x) attribute, but range extraction failed (invalid range list table index 0; OffsetEntryCount is 0, DW_AT_rnglists_base is 24), please file a bug and attach the file at the start of this error message
 
 .text
 rnglists:
Index: lldb/source/Target/SectionLoadList.cpp
===
--- lldb/source/Target/SectionLoadList.cpp
+++ lldb/source/Target/SectionLoadList.cpp
@@ -106,8 +106,8 @@
   ModuleSP curr_module_sp(ats_pos->second->GetModule());
   if (curr_module_sp) {
 module_sp->ReportWarning(
-"address 0x%16.16" PRIx64
-" maps to more than one section: %s.%s and %s.%s",
+"address {0:x16} maps to more than one section: {1}.{2} and "
+"{3}.{4}",
 load_addr, module_sp->GetFileSpec().GetFilename().GetCString(),
 section->GetName().GetCString(),
 

[Lldb-commits] [PATCH] D140999: [NFC][TargetParser] Deprecate llvm/Support/AArch64TargetParser.h

2023-01-05 Thread Fangrui Song via Phabricator via lldb-commits
MaskRay accepted this revision.
MaskRay added a comment.

I don't think it is necessary to deprecate the old header then delete it after 
16.0.0 is branched.
llvm/Support/AArch64TargetParser.h has very few open-source out-of-tree uses. 
Perhaps only ldc `driver/targetmachine.cpp` uses the header. So it is not worth 
extra expedience.

Changing the include to `#include "llvm/TargetParser/AArch64TargetParser.h"` is 
totally fine, though.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D140999/new/

https://reviews.llvm.org/D140999

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


[Lldb-commits] [PATCH] D140358: [lldb-vscode] Add support for disassembly view

2023-01-05 Thread Greg Clayton via Phabricator via lldb-commits
clayborg added inline comments.



Comment at: lldb/tools/lldb-vscode/lldb-vscode.cpp:2177
+  const auto bytes_offset = -instruction_offset * bytes_per_instruction;
+  auto start_addr = base_addr - bytes_offset;
+  const auto disassemble_bytes = instruction_count * bytes_per_instruction;

eloparco wrote:
> clayborg wrote:
> > This will work if the min and max opcode byte size are the same, like for 
> > arm64, the min and max are 4. This won't work for x86 or arm32 in thumb 
> > mode. So when backing up, we need to do an address lookup on the address we 
> > think we want to go to, and then adjust the starting address accordingly. 
> > Something like:
> > 
> > ```
> > SBAddress start_sbaddr = (base_addr - bytes_offset, g_vsc.target);
> > ```
> > now we have a section offset address that can tell us more about what it 
> > is. We can find the SBFunction or SBSymbol for this address and use those 
> > to find the right instructions. This will allow us to correctly disassemble 
> > code bytes. 
> > 
> > We can also look at the section that the memory comes from and see what the 
> > section contains. If the section is data, then emit something like:
> > ```
> > 0x1000 .byte 0x23
> > 0x1001 .byte 0x34
> > ...
> > ```
> > To find the section type we can do:
> > ```
> > SBSection section = start_sbaddr.GetSection();
> > if (section.IsValid() && section.GetSectionType() == 
> > lldb::eSectionTypeCode) {
> >  // Disassemble from a valid boundary
> > } else {
> >   // Emit a byte or long at a time with ".byte 0xXX" or other ASM directive 
> > for binary data
> > }
> > ```
> > We need to ensure we start disassembling on the correct instruction 
> > boundary as well as our math for "start_addr" might be in between actual 
> > opcode boundaries. If we are in a lldb::eSectionTypeCode, then we know we 
> > have instructions, and if we are not, then we can emit ".byte" or other 
> > binary data directives. So if we do have lldb::eSectionTypeCode as our 
> > section type, then we should have a function or symbol, and we can get 
> > instructions from those objects easily:
> > 
> > ```
> > if (section.IsValid() && section.GetSectionType() == 
> > lldb::eSectionTypeCode) {
> >  lldb::SBInstructionList instructions;
> >  lldb::SBFunction function = start_sbaddr.GetFunction();
> >  if (function.IsValid()) {
> > instructions = function.GetInstructions(g_vsc.target);
> >  } else {
> > symbol = start_sbaddr.GetSymbol();
> > if (symbol.IsValid())
> >   instructions = symbol.GetInstructions(g_vsc.target);
> > }
> > const size_t num_instrs = instructions.GetSize();
> > if (num_instrs > 0) {
> >   // we found instructions from a function or symbol and we need to 
> >   // find the matching instruction that we want to start from by iterating
> >   // over the instructions and finding the right address
> >   size_t matching_idx = num_instrs; // Invalid index
> >   for (size_t i=0; i > lldb::SBInstruction inst = instructions.GetInstructionAtIndex(i);
> > if (inst.GetAddress().GetLoadAddress(g_vsc.target) >= start_addr) {
> >   matching_idx = i;
> >   break;
> > }
> >   }
> >   if (matching_idx < num_instrs) {
> > // Now we can print the instructions from [matching_idx, num_instrs)
> > // then we need to repeat the search for the next function or symbol. 
> > // note there may be bytes between functions or symbols which we can 
> > disassemble
> > // by calling _get_instructions_from_memory(...) but we must find the 
> > next
> > // symbol or function boundary and get back on track
> >   }
> >   
> > ```
> Sorry, I should have provided a proper explanation.
> 
> I use the maximum instruction size as the "worst case". Basically, I need to 
> read a portion of memory but I do not know the start address and the size. 
> For the start address, if I want to read N instructions before `base_addr` I 
> need to read at least starting from `base_addr - N * max_instruction_size`: 
> if all instructions are of size `max_instruction_size` I will read exactly N 
> instructions; otherwise I will read more than N instructions and prune the 
> additional ones afterwards. Same for applies for the size.
> 
> Since `start_addr` is based on a "worst case", it may be an address in the 
> middle of an instruction. In that case, that first instruction will be 
> misinterpreted, but I think that is negligible.
> 
> The logic is similar to what is implemented in other VS Code extensions, like 
> https://github.com/vadimcn/vscode-lldb/blob/master/adapter/src/debug_session.rs#L1134.
> 
> Does it make sense?
The issue is, you might end up backing up by N bytes, and you might not end up 
on an opcode boundary. Lets say you have x86 disassembly like:

```
0x12e37 <+183>: 48 8b 4d f8  movq   -0x8(%rbp), %rcx
0x12e3b <+187>: 48 39 c8 cmpq   %rcx, %rax
0x12e3e <+190>: 0f 85 09 00 00 00jne0x12e4d 

[Lldb-commits] [PATCH] D141042: [lldb] Allow configuring on Windows with python interpreter within a junction

2023-01-05 Thread Greg Clayton via Phabricator via lldb-commits
clayborg accepted this revision.
clayborg added a comment.

lgtm


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D141042/new/

https://reviews.llvm.org/D141042

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


[Lldb-commits] [PATCH] D141087: Revert an unintentional API ABI break

2023-01-05 Thread Adrian Prantl via Phabricator via lldb-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rG69f2b5fcf1be: Revert an unintentional API ABI break 
(authored by aprantl).
Herald added a project: LLDB.
Herald added a subscriber: lldb-commits.

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D141087/new/

https://reviews.llvm.org/D141087

Files:
  lldb/include/lldb/lldb-enumerations.h


Index: lldb/include/lldb/lldb-enumerations.h
===
--- lldb/include/lldb/lldb-enumerations.h
+++ lldb/include/lldb/lldb-enumerations.h
@@ -437,7 +437,10 @@
 /// specification for ease of use and consistency.
 /// The enum -> string code is in Language.cpp, don't change this
 /// table without updating that code as well.
-enum LanguageType : uint16_t {
+///
+/// This datatype is used in SBExpressionOptions::SetLanguage() which
+/// makes this type API. Do not change its underlying storage type!
+enum LanguageType {
   eLanguageTypeUnknown = 0x,///< Unknown or invalid language value.
   eLanguageTypeC89 = 0x0001,///< ISO C:1989.
   eLanguageTypeC = 0x0002,  ///< Non-standardized C, such as K


Index: lldb/include/lldb/lldb-enumerations.h
===
--- lldb/include/lldb/lldb-enumerations.h
+++ lldb/include/lldb/lldb-enumerations.h
@@ -437,7 +437,10 @@
 /// specification for ease of use and consistency.
 /// The enum -> string code is in Language.cpp, don't change this
 /// table without updating that code as well.
-enum LanguageType : uint16_t {
+///
+/// This datatype is used in SBExpressionOptions::SetLanguage() which
+/// makes this type API. Do not change its underlying storage type!
+enum LanguageType {
   eLanguageTypeUnknown = 0x,///< Unknown or invalid language value.
   eLanguageTypeC89 = 0x0001,///< ISO C:1989.
   eLanguageTypeC = 0x0002,  ///< Non-standardized C, such as K
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] 69f2b5f - Revert an unintentional API ABI break

2023-01-05 Thread Adrian Prantl via lldb-commits

Author: Adrian Prantl
Date: 2023-01-05T13:43:12-08:00
New Revision: 69f2b5fcf1be2226181cce21066f072279ba5d14

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

LOG: Revert an unintentional API ABI break

lldb::LanguageType is used as a parameter in
SBExpressionOptions::SetLanguage(), which actually makes this type API
too. Commit 6eaedbb52f2a616e644e5acc7279c8b07c4cfe82 added a
`: uint16_t` to it, which broke binary compatibility for the SBAPI. This
patch reverts to the original enum.

I tried moving the entire enum into include/API, but that created a
cyclic module dependency between API and Utility. To keep things
simple, this just reverts to the original code and adds a warning.

rdar://103415402

Differential Revision: https://reviews.llvm.org/D141087

Added: 


Modified: 
lldb/include/lldb/lldb-enumerations.h

Removed: 




diff  --git a/lldb/include/lldb/lldb-enumerations.h 
b/lldb/include/lldb/lldb-enumerations.h
index f4748d0030f56..f92e63cc45f42 100644
--- a/lldb/include/lldb/lldb-enumerations.h
+++ b/lldb/include/lldb/lldb-enumerations.h
@@ -437,7 +437,10 @@ FLAGS_ENUM(WatchpointEventType){
 /// specification for ease of use and consistency.
 /// The enum -> string code is in Language.cpp, don't change this
 /// table without updating that code as well.
-enum LanguageType : uint16_t {
+///
+/// This datatype is used in SBExpressionOptions::SetLanguage() which
+/// makes this type API. Do not change its underlying storage type!
+enum LanguageType {
   eLanguageTypeUnknown = 0x,///< Unknown or invalid language value.
   eLanguageTypeC89 = 0x0001,///< ISO C:1989.
   eLanguageTypeC = 0x0002,  ///< Non-standardized C, such as K



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


[Lldb-commits] [PATCH] D140066: Add a final fallback technique to the old Darwin dynamic loader plugin to find the dyld_all_image_infos structure

2023-01-05 Thread Jonas Devlieghere via Phabricator via lldb-commits
JDevlieghere accepted this revision.
JDevlieghere added a comment.
This revision is now accepted and ready to land.

LGTM


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D140066/new/

https://reviews.llvm.org/D140066

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


[Lldb-commits] [PATCH] D141042: [lldb] Allow configuring on Windows with python interpreter within a junction

2023-01-05 Thread Jonas Devlieghere via Phabricator via lldb-commits
JDevlieghere accepted this revision.
JDevlieghere added a comment.
This revision is now accepted and ready to land.

Looks reasonable to me.

@lawrence_danna do you happen to remember why you wrote:

  exe = os.path.join(os.path.realpath(os.path.dirname(exe)), os.readlink(exe))

instead of

  exe = os.path.realpath(exe)

which seems like it should be equivalent? Aand you're doing a `realpath` call 
anyway...


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D141042/new/

https://reviews.llvm.org/D141042

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


[Lldb-commits] [PATCH] D140358: [lldb-vscode] Add support for disassembly view

2023-01-05 Thread Enrico Loparco via Phabricator via lldb-commits
eloparco updated this revision to Diff 486554.
eloparco added a comment.

Add integration tests for disassemble request


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D140358/new/

https://reviews.llvm.org/D140358

Files:
  lldb/include/lldb/API/SBTarget.h
  lldb/packages/Python/lldbsuite/test/tools/lldb-vscode/vscode.py
  lldb/source/API/SBTarget.cpp
  lldb/test/API/tools/lldb-vscode/disassemble/Makefile
  lldb/test/API/tools/lldb-vscode/disassemble/TestVSCode_disassemble.py
  lldb/test/API/tools/lldb-vscode/disassemble/main.cpp
  lldb/tools/lldb-vscode/CMakeLists.txt
  lldb/tools/lldb-vscode/DisassembledInstruction.cpp
  lldb/tools/lldb-vscode/DisassembledInstruction.h
  lldb/tools/lldb-vscode/JSONUtils.cpp
  lldb/tools/lldb-vscode/JSONUtils.h
  lldb/tools/lldb-vscode/LLDBUtils.cpp
  lldb/tools/lldb-vscode/LLDBUtils.h
  lldb/tools/lldb-vscode/VSCode.h
  lldb/tools/lldb-vscode/VSCodeForward.h
  lldb/tools/lldb-vscode/lldb-vscode.cpp

Index: lldb/tools/lldb-vscode/lldb-vscode.cpp
===
--- lldb/tools/lldb-vscode/lldb-vscode.cpp
+++ lldb/tools/lldb-vscode/lldb-vscode.cpp
@@ -1451,8 +1451,7 @@
   // which may affect the outcome of tests.
   bool source_init_file = GetBoolean(arguments, "sourceInitFile", true);
 
-  g_vsc.debugger =
-  lldb::SBDebugger::Create(source_init_file, log_cb, nullptr);
+  g_vsc.debugger = lldb::SBDebugger::Create(source_init_file, log_cb, nullptr);
   g_vsc.progress_event_thread = std::thread(ProgressEventThreadFunction);
 
   // Start our event thread so we can receive events from the debugger, target,
@@ -1542,6 +1541,8 @@
   // The debug adapter supports 'logMessage' in breakpoint.
   body.try_emplace("supportsLogPoints", true);
 
+  body.try_emplace("supportsDisassembleRequest", true);
+
   response.try_emplace("body", std::move(body));
   g_vsc.SendJSON(llvm::json::Value(std::move(response)));
 }
@@ -2117,6 +2118,163 @@
   g_vsc.SendJSON(llvm::json::Value(std::move(response)));
 }
 
+std::vector
+_get_instructions_from_memory(lldb::addr_t start, uint64_t count) {
+  lldb::SBProcess process = g_vsc.target.GetProcess();
+
+  lldb::SBError error;
+  std::vector buffer(count, 0);
+  const size_t bytes_read __attribute__((unused)) = process.ReadMemory(
+  start, static_cast(buffer.data()), count, error);
+  assert(bytes_read == count && error.Success() &&
+ "unable to read byte range from memory");
+
+  // If base_addr starts in the middle of an instruction,
+  // that first instruction will not be parsed correctly (negligible)
+  std::vector sb_instructions;
+  const auto base_addr = lldb::SBAddress(start, g_vsc.target);
+  lldb::SBInstructionList instructions =
+  g_vsc.target.GetInstructions(base_addr, buffer.data(), count);
+
+  for (size_t i = 0; i < instructions.GetSize(); i++) {
+auto instr = instructions.GetInstructionAtIndex(i);
+sb_instructions.emplace_back(instr);
+  }
+  return sb_instructions;
+}
+
+auto _handle_disassemble_positive_offset(lldb::addr_t base_addr,
+ int64_t instruction_offset,
+ uint64_t instruction_count) {
+  llvm::json::Array response_instructions;
+
+  auto start_addr =
+  lldb::SBAddress(base_addr + instruction_offset, g_vsc.target);
+  lldb::SBInstructionList instructions = g_vsc.target.ReadInstructions(
+  start_addr, instruction_offset + instruction_count);
+
+  std::vector dis_instructions;
+  const auto num_instrs_to_skip = static_cast(instruction_offset);
+  for (size_t i = num_instrs_to_skip; i < instructions.GetSize(); ++i) {
+lldb::SBInstruction instr = instructions.GetInstructionAtIndex(i);
+
+auto disass_instr =
+CreateDisassembledInstruction(DisassembledInstruction(instr));
+response_instructions.emplace_back(std::move(disass_instr));
+  }
+
+  return response_instructions;
+}
+
+auto _handle_disassemble_negative_offset(
+lldb::addr_t base_addr, int64_t instruction_offset,
+uint64_t instruction_count,
+std::optional memory_reference) {
+  llvm::json::Array response_instructions;
+
+  const auto bytes_per_instruction = g_vsc.target.GetMaximumOpcodeByteSize();
+  const auto bytes_offset = -instruction_offset * bytes_per_instruction;
+  auto start_addr = base_addr - bytes_offset;
+  const auto disassemble_bytes = instruction_count * bytes_per_instruction;
+
+  auto sb_instructions =
+  _get_instructions_from_memory(start_addr, disassemble_bytes);
+
+  // Find position of requested instruction
+  // in retrieved disassembled instructions
+  auto index = sb_instructions.size() + 1;
+  for (size_t i = 0; i < sb_instructions.size(); i++) {
+if (sb_instructions[i].GetAddress().GetLoadAddress(g_vsc.target) ==
+base_addr) {
+  index = i;
+  break;
+}
+  }
+  if (index == sb_instructions.size() + 1) {
+g_vsc.SendOutput(OutputType::Console,
+ 

[Lldb-commits] [PATCH] D140358: [lldb-vscode] Add support for disassembly view

2023-01-05 Thread Enrico Loparco via Phabricator via lldb-commits
eloparco updated this revision to Diff 486553.
eloparco added a comment.

Add integration tests for disassemble request


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D140358/new/

https://reviews.llvm.org/D140358

Files:
  lldb/include/lldb/API/SBTarget.h
  lldb/source/API/SBTarget.cpp
  lldb/tools/lldb-vscode/CMakeLists.txt
  lldb/tools/lldb-vscode/DisassembledInstruction.cpp
  lldb/tools/lldb-vscode/DisassembledInstruction.h
  lldb/tools/lldb-vscode/JSONUtils.cpp
  lldb/tools/lldb-vscode/JSONUtils.h
  lldb/tools/lldb-vscode/LLDBUtils.cpp
  lldb/tools/lldb-vscode/LLDBUtils.h
  lldb/tools/lldb-vscode/VSCode.h
  lldb/tools/lldb-vscode/VSCodeForward.h
  lldb/tools/lldb-vscode/lldb-vscode.cpp

Index: lldb/tools/lldb-vscode/lldb-vscode.cpp
===
--- lldb/tools/lldb-vscode/lldb-vscode.cpp
+++ lldb/tools/lldb-vscode/lldb-vscode.cpp
@@ -1451,8 +1451,7 @@
   // which may affect the outcome of tests.
   bool source_init_file = GetBoolean(arguments, "sourceInitFile", true);
 
-  g_vsc.debugger =
-  lldb::SBDebugger::Create(source_init_file, log_cb, nullptr);
+  g_vsc.debugger = lldb::SBDebugger::Create(source_init_file, log_cb, nullptr);
   g_vsc.progress_event_thread = std::thread(ProgressEventThreadFunction);
 
   // Start our event thread so we can receive events from the debugger, target,
@@ -1542,6 +1541,8 @@
   // The debug adapter supports 'logMessage' in breakpoint.
   body.try_emplace("supportsLogPoints", true);
 
+  body.try_emplace("supportsDisassembleRequest", true);
+
   response.try_emplace("body", std::move(body));
   g_vsc.SendJSON(llvm::json::Value(std::move(response)));
 }
@@ -2117,6 +2118,163 @@
   g_vsc.SendJSON(llvm::json::Value(std::move(response)));
 }
 
+std::vector
+_get_instructions_from_memory(lldb::addr_t start, uint64_t count) {
+  lldb::SBProcess process = g_vsc.target.GetProcess();
+
+  lldb::SBError error;
+  std::vector buffer(count, 0);
+  const size_t bytes_read __attribute__((unused)) = process.ReadMemory(
+  start, static_cast(buffer.data()), count, error);
+  assert(bytes_read == count && error.Success() &&
+ "unable to read byte range from memory");
+
+  // If base_addr starts in the middle of an instruction,
+  // that first instruction will not be parsed correctly (negligible)
+  std::vector sb_instructions;
+  const auto base_addr = lldb::SBAddress(start, g_vsc.target);
+  lldb::SBInstructionList instructions =
+  g_vsc.target.GetInstructions(base_addr, buffer.data(), count);
+
+  for (size_t i = 0; i < instructions.GetSize(); i++) {
+auto instr = instructions.GetInstructionAtIndex(i);
+sb_instructions.emplace_back(instr);
+  }
+  return sb_instructions;
+}
+
+auto _handle_disassemble_positive_offset(lldb::addr_t base_addr,
+ int64_t instruction_offset,
+ uint64_t instruction_count) {
+  llvm::json::Array response_instructions;
+
+  auto start_addr =
+  lldb::SBAddress(base_addr + instruction_offset, g_vsc.target);
+  lldb::SBInstructionList instructions = g_vsc.target.ReadInstructions(
+  start_addr, instruction_offset + instruction_count);
+
+  std::vector dis_instructions;
+  const auto num_instrs_to_skip = static_cast(instruction_offset);
+  for (size_t i = num_instrs_to_skip; i < instructions.GetSize(); ++i) {
+lldb::SBInstruction instr = instructions.GetInstructionAtIndex(i);
+
+auto disass_instr =
+CreateDisassembledInstruction(DisassembledInstruction(instr));
+response_instructions.emplace_back(std::move(disass_instr));
+  }
+
+  return response_instructions;
+}
+
+auto _handle_disassemble_negative_offset(
+lldb::addr_t base_addr, int64_t instruction_offset,
+uint64_t instruction_count,
+std::optional memory_reference) {
+  llvm::json::Array response_instructions;
+
+  const auto bytes_per_instruction = g_vsc.target.GetMaximumOpcodeByteSize();
+  const auto bytes_offset = -instruction_offset * bytes_per_instruction;
+  auto start_addr = base_addr - bytes_offset;
+  const auto disassemble_bytes = instruction_count * bytes_per_instruction;
+
+  auto sb_instructions =
+  _get_instructions_from_memory(start_addr, disassemble_bytes);
+
+  // Find position of requested instruction
+  // in retrieved disassembled instructions
+  auto index = sb_instructions.size() + 1;
+  for (size_t i = 0; i < sb_instructions.size(); i++) {
+if (sb_instructions[i].GetAddress().GetLoadAddress(g_vsc.target) ==
+base_addr) {
+  index = i;
+  break;
+}
+  }
+  if (index == sb_instructions.size() + 1) {
+g_vsc.SendOutput(OutputType::Console,
+ "current line not found in disassembled instructions");
+return response_instructions;
+  }
+
+  // Copy instructions into queue to easily manipulate them
+  std::deque disass_instructions;
+  for (auto  : sb_instructions)
+

[Lldb-commits] [PATCH] D140358: [lldb-vscode] Add support for disassembly view

2023-01-05 Thread Enrico Loparco via Phabricator via lldb-commits
eloparco updated this revision to Diff 486514.
eloparco added a comment.

Remove printf usage


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D140358/new/

https://reviews.llvm.org/D140358

Files:
  lldb/include/lldb/API/SBTarget.h
  lldb/source/API/SBTarget.cpp
  lldb/tools/lldb-vscode/CMakeLists.txt
  lldb/tools/lldb-vscode/DisassembledInstruction.cpp
  lldb/tools/lldb-vscode/DisassembledInstruction.h
  lldb/tools/lldb-vscode/JSONUtils.cpp
  lldb/tools/lldb-vscode/JSONUtils.h
  lldb/tools/lldb-vscode/LLDBUtils.cpp
  lldb/tools/lldb-vscode/LLDBUtils.h
  lldb/tools/lldb-vscode/VSCode.h
  lldb/tools/lldb-vscode/VSCodeForward.h
  lldb/tools/lldb-vscode/lldb-vscode.cpp

Index: lldb/tools/lldb-vscode/lldb-vscode.cpp
===
--- lldb/tools/lldb-vscode/lldb-vscode.cpp
+++ lldb/tools/lldb-vscode/lldb-vscode.cpp
@@ -1451,8 +1451,7 @@
   // which may affect the outcome of tests.
   bool source_init_file = GetBoolean(arguments, "sourceInitFile", true);
 
-  g_vsc.debugger =
-  lldb::SBDebugger::Create(source_init_file, log_cb, nullptr);
+  g_vsc.debugger = lldb::SBDebugger::Create(source_init_file, log_cb, nullptr);
   g_vsc.progress_event_thread = std::thread(ProgressEventThreadFunction);
 
   // Start our event thread so we can receive events from the debugger, target,
@@ -1542,6 +1541,8 @@
   // The debug adapter supports 'logMessage' in breakpoint.
   body.try_emplace("supportsLogPoints", true);
 
+  body.try_emplace("supportsDisassembleRequest", true);
+
   response.try_emplace("body", std::move(body));
   g_vsc.SendJSON(llvm::json::Value(std::move(response)));
 }
@@ -2117,6 +2118,163 @@
   g_vsc.SendJSON(llvm::json::Value(std::move(response)));
 }
 
+std::vector
+_get_instructions_from_memory(lldb::addr_t start, uint64_t count) {
+  lldb::SBProcess process = g_vsc.target.GetProcess();
+
+  lldb::SBError error;
+  std::vector buffer(count, 0);
+  const size_t bytes_read __attribute__((unused)) = process.ReadMemory(
+  start, static_cast(buffer.data()), count, error);
+  assert(bytes_read == count && error.Success() &&
+ "unable to read byte range from memory");
+
+  // If base_addr starts in the middle of an instruction,
+  // that first instruction will not be parsed correctly (negligible)
+  std::vector sb_instructions;
+  const auto base_addr = lldb::SBAddress(start, g_vsc.target);
+  lldb::SBInstructionList instructions =
+  g_vsc.target.GetInstructions(base_addr, buffer.data(), count);
+
+  for (size_t i = 0; i < instructions.GetSize(); i++) {
+auto instr = instructions.GetInstructionAtIndex(i);
+sb_instructions.emplace_back(instr);
+  }
+  return sb_instructions;
+}
+
+auto _handle_disassemble_positive_offset(lldb::addr_t base_addr,
+ int64_t instruction_offset,
+ uint64_t instruction_count) {
+  llvm::json::Array response_instructions;
+
+  auto start_addr =
+  lldb::SBAddress(base_addr + instruction_offset, g_vsc.target);
+  lldb::SBInstructionList instructions = g_vsc.target.ReadInstructions(
+  start_addr, instruction_offset + instruction_count);
+
+  std::vector dis_instructions;
+  const auto num_instrs_to_skip = static_cast(instruction_offset);
+  for (size_t i = num_instrs_to_skip; i < instructions.GetSize(); ++i) {
+lldb::SBInstruction instr = instructions.GetInstructionAtIndex(i);
+
+auto disass_instr =
+CreateDisassembledInstruction(DisassembledInstruction(instr));
+response_instructions.emplace_back(std::move(disass_instr));
+  }
+
+  return response_instructions;
+}
+
+auto _handle_disassemble_negative_offset(
+lldb::addr_t base_addr, int64_t instruction_offset,
+uint64_t instruction_count,
+std::optional memory_reference) {
+  llvm::json::Array response_instructions;
+
+  const auto bytes_per_instruction = g_vsc.target.GetMaximumOpcodeByteSize();
+  const auto bytes_offset = -instruction_offset * bytes_per_instruction;
+  auto start_addr = base_addr - bytes_offset;
+  const auto disassemble_bytes = instruction_count * bytes_per_instruction;
+
+  auto sb_instructions =
+  _get_instructions_from_memory(start_addr, disassemble_bytes);
+
+  // Find position of requested instruction
+  // in retrieved disassembled instructions
+  auto index = sb_instructions.size() + 1;
+  for (size_t i = 0; i < sb_instructions.size(); i++) {
+if (sb_instructions[i].GetAddress().GetLoadAddress(g_vsc.target) ==
+base_addr) {
+  index = i;
+  break;
+}
+  }
+  if (index == sb_instructions.size() + 1) {
+g_vsc.SendOutput(OutputType::Console,
+ "current line not found in disassembled instructions");
+return response_instructions;
+  }
+
+  // Copy instructions into queue to easily manipulate them
+  std::deque disass_instructions;
+  for (auto  : sb_instructions)
+

[Lldb-commits] [PATCH] D141042: [lldb] Allow configuring on Windows with python interpreter within a junction

2023-01-05 Thread Markus Böck via Phabricator via lldb-commits
zero9178 created this revision.
zero9178 added reviewers: JDevlieghere, lawrence_danna, clayborg, labath, 
jingham.
Herald added a project: All.
zero9178 requested review of this revision.
Herald added a project: LLDB.
Herald added a subscriber: lldb-commits.

The current implementation nicely takes into account when the python 
interpreter is symlinked (or transitively within a symlinked directory). Sadly, 
`os.path.islink` returns `false` on Windows if instead of Windows symlinks, 
junctions are used. This has caused me issues after I started using `scoop` as 
my package manager on Windows, which creates junctions instead of symlinks.
The fix proposed in this patch is to check whether `realpath` returns a 
different path to `exe`, and if it does, to simply try again with that path. 
The code could also be simplified since `sys.executable` is guaranteed to be 
absolute, and `os.readlink`, which can return a relative path, is no longer 
used.

Tested on Windows 11 with Python 3.11 as interpereter and Ubuntu 18.04 with 
Python 3.6


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D141042

Files:
  lldb/bindings/python/get-python-config.py


Index: lldb/bindings/python/get-python-config.py
===
--- lldb/bindings/python/get-python-config.py
+++ lldb/bindings/python/get-python-config.py
@@ -51,8 +51,10 @@
 break
 except ValueError:
 tried.append(exe)
-if os.path.islink(exe):
-exe = os.path.join(os.path.realpath(os.path.dirname(exe)), 
os.readlink(exe))
+# Retry if the executable is symlinked or similar.
+# This is roughly equal to os.path.islink, except it also 
works for junctions on Windows.
+if os.path.realpath(exe) != exe:
+exe = os.path.realpath(exe)
 continue
 else:
 print("Could not find a relative path to sys.executable 
under sys.prefix", file=sys.stderr)


Index: lldb/bindings/python/get-python-config.py
===
--- lldb/bindings/python/get-python-config.py
+++ lldb/bindings/python/get-python-config.py
@@ -51,8 +51,10 @@
 break
 except ValueError:
 tried.append(exe)
-if os.path.islink(exe):
-exe = os.path.join(os.path.realpath(os.path.dirname(exe)), os.readlink(exe))
+# Retry if the executable is symlinked or similar.
+# This is roughly equal to os.path.islink, except it also works for junctions on Windows.
+if os.path.realpath(exe) != exe:
+exe = os.path.realpath(exe)
 continue
 else:
 print("Could not find a relative path to sys.executable under sys.prefix", file=sys.stderr)
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [PATCH] D140358: [lldb-vscode] Add support for disassembly view

2023-01-05 Thread Enrico Loparco via Phabricator via lldb-commits
eloparco added inline comments.



Comment at: lldb/tools/lldb-vscode/lldb-vscode.cpp:2194
+  if (index == sb_instructions.size() + 1) {
+fprintf(stderr, "current line not found in disassembled instructions\n");
+return response_instructions;

clayborg wrote:
> Remove any and all printf, or fprintf statements. You can't print anything to 
> stderr or stdout as this is where the DAP packets are get emitted to. We do 
> make it so this won't affect lldb-vscode by doing some magic with the 
> STDOUT/STDERR file handles, but this output will be sent to /dev/null most 
> likely. You can print something to a console (using "g_vsc.SendOutput(...)" 
> is one way).
I suppose I have to replace `llvm::errs()` too, right?


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D140358/new/

https://reviews.llvm.org/D140358

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


[Lldb-commits] [PATCH] D140358: [lldb-vscode] Add support for disassembly view

2023-01-05 Thread Enrico Loparco via Phabricator via lldb-commits
eloparco added inline comments.



Comment at: lldb/tools/lldb-vscode/lldb-vscode.cpp:2177
+  const auto bytes_offset = -instruction_offset * bytes_per_instruction;
+  auto start_addr = base_addr - bytes_offset;
+  const auto disassemble_bytes = instruction_count * bytes_per_instruction;

clayborg wrote:
> This will work if the min and max opcode byte size are the same, like for 
> arm64, the min and max are 4. This won't work for x86 or arm32 in thumb mode. 
> So when backing up, we need to do an address lookup on the address we think 
> we want to go to, and then adjust the starting address accordingly. Something 
> like:
> 
> ```
> SBAddress start_sbaddr = (base_addr - bytes_offset, g_vsc.target);
> ```
> now we have a section offset address that can tell us more about what it is. 
> We can find the SBFunction or SBSymbol for this address and use those to find 
> the right instructions. This will allow us to correctly disassemble code 
> bytes. 
> 
> We can also look at the section that the memory comes from and see what the 
> section contains. If the section is data, then emit something like:
> ```
> 0x1000 .byte 0x23
> 0x1001 .byte 0x34
> ...
> ```
> To find the section type we can do:
> ```
> SBSection section = start_sbaddr.GetSection();
> if (section.IsValid() && section.GetSectionType() == lldb::eSectionTypeCode) {
>  // Disassemble from a valid boundary
> } else {
>   // Emit a byte or long at a time with ".byte 0xXX" or other ASM directive 
> for binary data
> }
> ```
> We need to ensure we start disassembling on the correct instruction boundary 
> as well as our math for "start_addr" might be in between actual opcode 
> boundaries. If we are in a lldb::eSectionTypeCode, then we know we have 
> instructions, and if we are not, then we can emit ".byte" or other binary 
> data directives. So if we do have lldb::eSectionTypeCode as our section type, 
> then we should have a function or symbol, and we can get instructions from 
> those objects easily:
> 
> ```
> if (section.IsValid() && section.GetSectionType() == lldb::eSectionTypeCode) {
>  lldb::SBInstructionList instructions;
>  lldb::SBFunction function = start_sbaddr.GetFunction();
>  if (function.IsValid()) {
> instructions = function.GetInstructions(g_vsc.target);
>  } else {
> symbol = start_sbaddr.GetSymbol();
> if (symbol.IsValid())
>   instructions = symbol.GetInstructions(g_vsc.target);
> }
> const size_t num_instrs = instructions.GetSize();
> if (num_instrs > 0) {
>   // we found instructions from a function or symbol and we need to 
>   // find the matching instruction that we want to start from by iterating
>   // over the instructions and finding the right address
>   size_t matching_idx = num_instrs; // Invalid index
>   for (size_t i=0; i lldb::SBInstruction inst = instructions.GetInstructionAtIndex(i);
> if (inst.GetAddress().GetLoadAddress(g_vsc.target) >= start_addr) {
>   matching_idx = i;
>   break;
> }
>   }
>   if (matching_idx < num_instrs) {
> // Now we can print the instructions from [matching_idx, num_instrs)
> // then we need to repeat the search for the next function or symbol. 
> // note there may be bytes between functions or symbols which we can 
> disassemble
> // by calling _get_instructions_from_memory(...) but we must find the next
> // symbol or function boundary and get back on track
>   }
>   
> ```
Sorry, I should have provided a proper explanation.

I use the maximum instruction size as the "worst case". Basically, I need to 
read a portion of memory but I do not know the start address and the size. For 
the start address, if I want to read N instructions before `base_addr` I need 
to read at least starting from `base_addr - N * max_instruction_size`: if all 
instructions are of size `max_instruction_size` I will read exactly N 
instructions; otherwise I will read more than N instructions and prune the 
additional ones afterwards. Same for applies for the size.

Since `start_addr` is based on a "worst case", it may be an address in the 
middle of an instruction. In that case, that first instruction will be 
misinterpreted, but I think that is negligible.

The logic is similar to what is implemented in other VS Code extensions, like 
https://github.com/vadimcn/vscode-lldb/blob/master/adapter/src/debug_session.rs#L1134.

Does it make sense?


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D140358/new/

https://reviews.llvm.org/D140358

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


[Lldb-commits] [PATCH] D140999: [NFC][TargetParser] Deprecate llvm/Support/AArch64TargetParser.h

2023-01-05 Thread Lucas Prates via Phabricator via lldb-commits
pratlucas accepted this revision.
pratlucas added a comment.
This revision is now accepted and ready to land.

LGTM.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D140999/new/

https://reviews.llvm.org/D140999

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