kuilpd created this revision.
kuilpd added reviewers: asl, bulbazord, DavidSpickett.
kuilpd added projects: LLDB, All.
Herald added subscribers: Michael137, JDevlieghere, arichardson.
kuilpd requested review of this revision.
Herald added a subscriber: lldb-commits.
Expression evaluation allocates memory for storing intermediate data during
evaluation. For it to work properly it has to be allocated within target's
available address space, for example within first 0xFFFF bytes for the 16-bit
MSP430. The memory for such targets can be very tightly packed, but not all
targets support GetMemoryRegionInfo API to pick an unused region, like MSP430
with MSPDebug GDB server.
These settings allow the programmer to manually pick precisely where and how
much memory to allocate for expression evaluation in order not to overlap with
existing data in process memory.
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D149262
Files:
lldb/include/lldb/Target/Target.h
lldb/source/Expression/IRMemoryMap.cpp
lldb/source/Expression/LLVMUserExpression.cpp
lldb/source/Target/Target.cpp
lldb/source/Target/TargetProperties.td
Index: lldb/source/Target/TargetProperties.td
===================================================================
--- lldb/source/Target/TargetProperties.td
+++ lldb/source/Target/TargetProperties.td
@@ -24,6 +24,15 @@
DefaultUnsignedValue<5>,
Desc<"The maximum amount of errors to emit while parsing an expression. "
"A value of 0 means to always continue parsing if possible.">;
+ def ExprAllocAddress: Property<"expr-alloc-address", "UInt64">,
+ DefaultUnsignedValue<0>,
+ Desc<"Start address within the process address space of memory allocation for expression evaluation.">;
+ def ExprAllocSize: Property<"expr-alloc-size", "UInt64">,
+ DefaultUnsignedValue<0>,
+ Desc<"Amount of memory in bytes to allocate for expression evaluation.">;
+ def ExprAllocAlign: Property<"expr-alloc-align", "UInt64">,
+ DefaultUnsignedValue<0>,
+ Desc<"Alignment for each memory allocation for expression evaluation.">;
def PreferDynamic: Property<"prefer-dynamic-value", "Enum">,
DefaultEnumValue<"eDynamicDontRunTarget">,
EnumValues<"OptionEnumValues(g_dynamic_value_types)">,
Index: lldb/source/Target/Target.cpp
===================================================================
--- lldb/source/Target/Target.cpp
+++ lldb/source/Target/Target.cpp
@@ -4587,6 +4587,24 @@
nullptr, idx, g_target_properties[idx].default_uint_value);
}
+uint64_t TargetProperties::GetExprAllocAddress() const {
+ const uint32_t idx = ePropertyExprAllocAddress;
+ return m_collection_sp->GetPropertyAtIndexAsUInt64(
+ nullptr, idx, g_target_properties[idx].default_uint_value);
+}
+
+uint64_t TargetProperties::GetExprAllocSize() const {
+ const uint32_t idx = ePropertyExprAllocSize;
+ return m_collection_sp->GetPropertyAtIndexAsUInt64(
+ nullptr, idx, g_target_properties[idx].default_uint_value);
+}
+
+uint64_t TargetProperties::GetExprAllocAlign() const {
+ const uint32_t idx = ePropertyExprAllocAlign;
+ return m_collection_sp->GetPropertyAtIndexAsUInt64(
+ nullptr, idx, g_target_properties[idx].default_uint_value);
+}
+
bool TargetProperties::GetBreakpointsConsultPlatformAvoidList() {
const uint32_t idx = ePropertyBreakpointUseAvoidList;
return m_collection_sp->GetPropertyAtIndexAsBoolean(
Index: lldb/source/Expression/LLVMUserExpression.cpp
===================================================================
--- lldb/source/Expression/LLVMUserExpression.cpp
+++ lldb/source/Expression/LLVMUserExpression.cpp
@@ -334,8 +334,9 @@
Status alloc_error;
auto arch = target->GetArchitecture().GetTriple().getArch();
- const size_t stack_frame_size =
- arch == llvm::Triple::msp430 ? 512 : 512 * 1024;
+ size_t stack_frame_size = target->GetExprAllocSize();
+ if (stack_frame_size == 0)
+ stack_frame_size = arch == llvm::Triple::msp430 ? 512 : 512 * 1024;
const bool zero_memory = false;
Index: lldb/source/Expression/IRMemoryMap.cpp
===================================================================
--- lldb/source/Expression/IRMemoryMap.cpp
+++ lldb/source/Expression/IRMemoryMap.cpp
@@ -92,26 +92,26 @@
ret = llvm::alignTo(addr + alloc_size, 4096);
}
+ uint64_t end_of_memory;
+ switch (GetAddressByteSize()) {
+ case 2:
+ end_of_memory = 0xffffull;
+ break;
+ case 4:
+ end_of_memory = 0xffffffffull;
+ break;
+ case 8:
+ end_of_memory = 0xffffffffffffffffull;
+ break;
+ default:
+ lldbassert(false && "Invalid address size.");
+ return LLDB_INVALID_ADDRESS;
+ }
+
// Now, if it's possible to use the GetMemoryRegionInfo API to detect mapped
// regions, walk forward through memory until a region is found that has
// adequate space for our allocation.
if (process_is_alive) {
- uint64_t end_of_memory;
- switch (process_sp->GetAddressByteSize()) {
- case 2:
- end_of_memory = 0xffffull;
- break;
- case 4:
- end_of_memory = 0xffffffffull;
- break;
- case 8:
- end_of_memory = 0xffffffffffffffffull;
- break;
- default:
- lldbassert(false && "Invalid address size.");
- return LLDB_INVALID_ADDRESS;
- }
-
MemoryRegionInfo region_info;
Status err = process_sp->GetMemoryRegionInfo(ret, region_info);
if (err.Success()) {
@@ -147,29 +147,41 @@
// to the end of the allocations we've already reported, or use a 'sensible'
// default if this is our first allocation.
if (m_allocations.empty()) {
- uint32_t address_byte_size = GetAddressByteSize();
- if (address_byte_size != UINT32_MAX) {
- switch (address_byte_size) {
- case 2:
- ret = 0x8000ull;
- break;
- case 4:
- ret = 0xee000000ull;
- break;
- case 8:
- ret = 0xdead0fff00000000ull;
- break;
- default:
- lldbassert(false && "Invalid address size.");
+ uint64_t alloc_address = target_sp->GetExprAllocAddress();
+ if (alloc_address > 0) {
+ if (alloc_address >= end_of_memory) {
+ lldbassert(0 && "The allocation address for expression evaluation must "
+ "be within process address space");
return LLDB_INVALID_ADDRESS;
}
+ ret = alloc_address;
+ } else {
+ uint32_t address_byte_size = GetAddressByteSize();
+ if (address_byte_size != UINT32_MAX) {
+ switch (address_byte_size) {
+ case 2:
+ ret = 0x8000ull;
+ break;
+ case 4:
+ ret = 0xee000000ull;
+ break;
+ case 8:
+ ret = 0xdead0fff00000000ull;
+ break;
+ default:
+ lldbassert(false && "Invalid address size.");
+ return LLDB_INVALID_ADDRESS;
+ }
+ }
}
} else {
auto back = m_allocations.rbegin();
lldb::addr_t addr = back->first;
size_t alloc_size = back->second.m_size;
auto arch = target_sp->GetArchitecture().GetTriple().getArch();
- auto align = arch == llvm::Triple::msp430 ? 512 : 4096;
+ uint64_t align = target_sp->GetExprAllocAlign();
+ if (align == 0)
+ align = arch == llvm::Triple::msp430 ? 512 : 4096;
ret = llvm::alignTo(addr + alloc_size, align);
}
Index: lldb/include/lldb/Target/Target.h
===================================================================
--- lldb/include/lldb/Target/Target.h
+++ lldb/include/lldb/Target/Target.h
@@ -204,6 +204,12 @@
uint64_t GetExprErrorLimit() const;
+ uint64_t GetExprAllocAddress() const;
+
+ uint64_t GetExprAllocSize() const;
+
+ uint64_t GetExprAllocAlign() const;
+
bool GetUseHexImmediates() const;
bool GetUseFastStepping() const;
_______________________________________________
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits