[Lldb-commits] [lldb] d839f65 - [wasm] Always treat DWARF expression addresses as load addresses

Philip Pfaffe via lldb-commits lldb-commits at lists.llvm.org
Wed Nov 2 05:14:58 PDT 2022


Author: Philip Pfaffe
Date: 2022-11-02T12:11:53Z
New Revision: d839f654586a4f3a84b334fcc2c986343a1d7f98

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

LOG: [wasm] Always treat DWARF expression addresses as load addresses

When resolving absolute addresses for DW_OP_addr or DW_OP_addrx, these are always load addresses rather than file addresses in wasm.

Reviewed By: DavidSpickett

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

Added: 
    

Modified: 
    lldb/source/Expression/DWARFExpression.cpp
    lldb/unittests/Expression/DWARFExpressionTest.cpp

Removed: 
    


################################################################################
diff  --git a/lldb/source/Expression/DWARFExpression.cpp b/lldb/source/Expression/DWARFExpression.cpp
index 1ccda944cd013..3f302e53c00e1 100644
--- a/lldb/source/Expression/DWARFExpression.cpp
+++ b/lldb/source/Expression/DWARFExpression.cpp
@@ -847,10 +847,12 @@ bool DWARFExpression::Evaluate(
 
   Process *process = nullptr;
   StackFrame *frame = nullptr;
+  Target *target = nullptr;
 
   if (exe_ctx) {
     process = exe_ctx->GetProcessPtr();
     frame = exe_ctx->GetFramePtr();
+    target = exe_ctx->GetTargetPtr();
   }
   if (reg_ctx == nullptr && frame)
     reg_ctx = frame->GetRegisterContext().get();
@@ -906,12 +908,19 @@ bool DWARFExpression::Evaluate(
     // address and whose size is the size of an address on the target machine.
     case DW_OP_addr:
       stack.push_back(Scalar(opcodes.GetAddress(&offset)));
-      stack.back().SetValueType(Value::ValueType::FileAddress);
-      // Convert the file address to a load address, so subsequent
-      // DWARF operators can operate on it.
-      if (frame)
-        stack.back().ConvertToLoadAddress(module_sp.get(),
-                                          frame->CalculateTarget().get());
+      if (target &&
+          target->GetArchitecture().GetCore() == ArchSpec::eCore_wasm32) {
+        // wasm file sections aren't mapped into memory, therefore addresses can
+        // never point into a file section and are always LoadAddresses.
+        stack.back().SetValueType(Value::ValueType::LoadAddress);
+      } else {
+        stack.back().SetValueType(Value::ValueType::FileAddress);
+        // Convert the file address to a load address, so subsequent
+        // DWARF operators can operate on it.
+        if (frame)
+          stack.back().ConvertToLoadAddress(module_sp.get(),
+                                            frame->CalculateTarget().get());
+      }
       break;
 
     // The DW_OP_addr_sect_offset4 is used for any location expressions in
@@ -2507,7 +2516,14 @@ bool DWARFExpression::Evaluate(
       uint64_t index = opcodes.GetULEB128(&offset);
       lldb::addr_t value = dwarf_cu->ReadAddressFromDebugAddrSection(index);
       stack.push_back(Scalar(value));
-      stack.back().SetValueType(Value::ValueType::FileAddress);
+      if (target &&
+          target->GetArchitecture().GetCore() == ArchSpec::eCore_wasm32) {
+        // wasm file sections aren't mapped into memory, therefore addresses can
+        // never point into a file section and are always LoadAddresses.
+        stack.back().SetValueType(Value::ValueType::LoadAddress);
+      } else {
+        stack.back().SetValueType(Value::ValueType::FileAddress);
+      }
     } break;
 
     // OPCODE: DW_OP_GNU_const_index

diff  --git a/lldb/unittests/Expression/DWARFExpressionTest.cpp b/lldb/unittests/Expression/DWARFExpressionTest.cpp
index 35a064fc14bd8..4251eb0aecda9 100644
--- a/lldb/unittests/Expression/DWARFExpressionTest.cpp
+++ b/lldb/unittests/Expression/DWARFExpressionTest.cpp
@@ -8,6 +8,7 @@
 
 #include "lldb/Expression/DWARFExpression.h"
 #include "Plugins/Platform/Linux/PlatformLinux.h"
+#include "Plugins/SymbolFile/DWARF/DWARFDebugInfo.h"
 #include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
 #include "TestingSupport/Symbol/YAMLModuleTester.h"
 #include "lldb/Core/Debugger.h"
@@ -401,3 +402,115 @@ TEST_F(DWARFExpressionMockProcessTest, DW_OP_deref) {
       Evaluate({DW_OP_lit4, DW_OP_deref, DW_OP_stack_value}, {}, {}, &exe_ctx),
       llvm::HasValue(GetScalar(32, 0x07060504, false)));
 }
+
+TEST_F(DWARFExpressionMockProcessTest, WASM_DW_OP_addr) {
+  // Set up a wasm target
+  ArchSpec arch("wasm32-unknown-unknown-wasm");
+  lldb::PlatformSP host_platform_sp =
+      platform_linux::PlatformLinux::CreateInstance(true, &arch);
+  ASSERT_TRUE(host_platform_sp);
+  Platform::SetHostPlatform(host_platform_sp);
+  lldb::DebuggerSP debugger_sp = Debugger::CreateInstance();
+  ASSERT_TRUE(debugger_sp);
+  lldb::TargetSP target_sp;
+  lldb::PlatformSP platform_sp;
+  debugger_sp->GetTargetList().CreateTarget(*debugger_sp, "", arch,
+                                            lldb_private::eLoadDependentsNo,
+                                            platform_sp, target_sp);
+
+  ExecutionContext exe_ctx(target_sp, false);
+  // DW_OP_addr takes a single operand of address size width:
+  uint8_t expr[] = {DW_OP_addr, 0x40, 0x0, 0x0, 0x0};
+  DataExtractor extractor(expr, sizeof(expr), lldb::eByteOrderLittle,
+                          /*addr_size*/ 4);
+  Value result;
+  Status status;
+  ASSERT_TRUE(DWARFExpression::Evaluate(
+      &exe_ctx, /*reg_ctx*/ nullptr, /*module_sp*/ {}, extractor,
+      /*unit*/ nullptr, lldb::eRegisterKindLLDB,
+      /*initial_value_ptr*/ nullptr,
+      /*object_address_ptr*/ nullptr, result, &status))
+      << status.ToError();
+
+  ASSERT_EQ(result.GetValueType(), Value::ValueType::LoadAddress);
+}
+
+TEST_F(DWARFExpressionMockProcessTest, WASM_DW_OP_addr_index) {
+  const char *yamldata = R"(
+--- !ELF
+FileHeader:
+  Class:   ELFCLASS64
+  Data:    ELFDATA2LSB
+  Type:    ET_EXEC
+  Machine: EM_386
+DWARF:
+  debug_abbrev:
+    - Table:
+        - Code:            0x00000001
+          Tag:             DW_TAG_compile_unit
+          Children:        DW_CHILDREN_no
+          Attributes:
+            - Attribute:       DW_AT_addr_base
+              Form:            DW_FORM_sec_offset
+
+  debug_info:
+    - Version:         5
+      AddrSize:        4
+      UnitType:        DW_UT_compile
+      Entries:
+        - AbbrCode:        0x00000001
+          Values:
+            - Value:           0x8 # Offset of the first Address past the header
+        - AbbrCode:        0x0
+
+  debug_addr:
+    - Version: 5
+      AddressSize: 4
+      Entries:
+        - Address: 0x1234
+        - Address: 0x5678
+)";
+
+  // Can't use DWARFExpressionTester from above because subsystems overlap with
+  // the fixture.
+  SubsystemRAII<ObjectFileELF, SymbolFileDWARF> subsystems;
+  llvm::Expected<TestFile> file = TestFile::fromYaml(yamldata);
+  EXPECT_THAT_EXPECTED(file, llvm::Succeeded());
+  auto module_sp = std::make_shared<Module>(file->moduleSpec());
+  auto *dwarf_cu = llvm::cast<SymbolFileDWARF>(module_sp->GetSymbolFile())
+                       ->DebugInfo()
+                       .GetUnitAtIndex(0);
+  ASSERT_TRUE(dwarf_cu);
+  dwarf_cu->ExtractDIEsIfNeeded();
+
+  // Set up a wasm target
+  ArchSpec arch("wasm32-unknown-unknown-wasm");
+  lldb::PlatformSP host_platform_sp =
+      platform_linux::PlatformLinux::CreateInstance(true, &arch);
+  ASSERT_TRUE(host_platform_sp);
+  Platform::SetHostPlatform(host_platform_sp);
+  lldb::DebuggerSP debugger_sp = Debugger::CreateInstance();
+  ASSERT_TRUE(debugger_sp);
+  lldb::TargetSP target_sp;
+  lldb::PlatformSP platform_sp;
+  debugger_sp->GetTargetList().CreateTarget(*debugger_sp, "", arch,
+                                            lldb_private::eLoadDependentsNo,
+                                            platform_sp, target_sp);
+
+  ExecutionContext exe_ctx(target_sp, false);
+  // DW_OP_addrx takes a single leb128 operand, the index in the addr table:
+  uint8_t expr[] = {DW_OP_addrx, 0x01};
+  DataExtractor extractor(expr, sizeof(expr), lldb::eByteOrderLittle,
+                          /*addr_size*/ 4);
+  Value result;
+  Status status;
+  ASSERT_TRUE(DWARFExpression::Evaluate(
+      &exe_ctx, /*reg_ctx*/ nullptr, /*module_sp*/ {}, extractor, dwarf_cu,
+      lldb::eRegisterKindLLDB,
+      /*initial_value_ptr*/ nullptr,
+      /*object_address_ptr*/ nullptr, result, &status))
+      << status.ToError();
+
+  ASSERT_EQ(result.GetValueType(), Value::ValueType::LoadAddress);
+  ASSERT_EQ(result.GetScalar().UInt(), 0x5678u);
+}


        


More information about the lldb-commits mailing list