Index: lldb/include/lldb/Target/ABI.h =================================================================== --- lldb/include/lldb/Target/ABI.h +++ lldb/include/lldb/Target/ABI.h @@ -147,6 +147,8 @@ virtual bool GetPointerReturnRegister(const char *&name) { return false; } + virtual uint64_t GetStackFrameSize() { return 512 * 1024; } + static lldb::ABISP FindPlugin(lldb::ProcessSP process_sp, const ArchSpec &arch); protected: 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; 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,40 @@ // 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 = 4096; ret = llvm::alignTo(addr + alloc_size, align); } Index: lldb/source/Expression/LLVMUserExpression.cpp =================================================================== --- lldb/source/Expression/LLVMUserExpression.cpp +++ lldb/source/Expression/LLVMUserExpression.cpp @@ -23,6 +23,7 @@ #include "lldb/Symbol/SymbolVendor.h" #include "lldb/Symbol/Type.h" #include "lldb/Symbol/VariableList.h" +#include "lldb/Target/ABI.h" #include "lldb/Target/ExecutionContext.h" #include "lldb/Target/Process.h" #include "lldb/Target/StackFrame.h" @@ -34,6 +35,7 @@ #include "lldb/Utility/Log.h" #include "lldb/Utility/StreamString.h" +using namespace lldb; using namespace lldb_private; char LLVMUserExpression::ID; @@ -333,9 +335,17 @@ if (m_can_interpret && m_stack_frame_bottom == LLDB_INVALID_ADDRESS) { 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) { + Process *process_sp; + ABISP abi_sp; + if ((process_sp = exe_ctx.GetProcessPtr()) && + (abi_sp = process_sp->GetABI())) { + stack_frame_size = abi_sp->GetStackFrameSize(); + } else { + stack_frame_size = 512 * 1024; + } + } const bool zero_memory = false; Index: lldb/source/Plugins/ABI/MSP430/ABISysV_msp430.h =================================================================== --- lldb/source/Plugins/ABI/MSP430/ABISysV_msp430.h +++ lldb/source/Plugins/ABI/MSP430/ABISysV_msp430.h @@ -55,6 +55,8 @@ const lldb_private::RegisterInfo * GetRegisterInfoArray(uint32_t &count) override; + uint64_t GetStackFrameSize() override { return 512; } + //------------------------------------------------------------------ // Static Functions //------------------------------------------------------------------ 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/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)">,