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 lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits