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

Greg Clayton via Phabricator via lldb-commits lldb-commits at lists.llvm.org
Wed Jan 4 18:01:41 PST 2023


clayborg requested changes to this revision.
clayborg added a comment.
This revision now requires changes to proceed.

Sorry for delay, I was on recharge for all of December.



================
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;
----------------
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:
```
0x00001000 .byte 0x23
0x00001001 .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<num_instrs; ++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
  }
  
```


================
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;
----------------
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).


================
Comment at: lldb/tools/lldb-vscode/lldb-vscode.cpp:2244
+  auto base_addr = hex_string_to_addr(memory_reference);
+  if (hex_string_to_addr(memory_reference) == 0) {
+    success = false;
----------------



Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D140358



More information about the lldb-commits mailing list