diff options
author | emaste <emaste@FreeBSD.org> | 2013-11-06 16:48:53 +0000 |
---|---|---|
committer | emaste <emaste@FreeBSD.org> | 2013-11-06 16:48:53 +0000 |
commit | c727fe695d28799acb499e9961f11ec07d4f9fe2 (patch) | |
tree | 56d79f94966870db1cecd65a7264510a25fd1cba /source/Plugins/Process/Utility | |
parent | 2e8c9206a971efee1b77ad2ae852265d6f4ecaa0 (diff) | |
download | FreeBSD-src-c727fe695d28799acb499e9961f11ec07d4f9fe2.zip FreeBSD-src-c727fe695d28799acb499e9961f11ec07d4f9fe2.tar.gz |
Import lldb as of SVN r194122
Sponsored by: DARPA, AFRL
Diffstat (limited to 'source/Plugins/Process/Utility')
6 files changed, 509 insertions, 64 deletions
diff --git a/source/Plugins/Process/Utility/DynamicRegisterInfo.cpp b/source/Plugins/Process/Utility/DynamicRegisterInfo.cpp index 0c95d66..dc90b7a 100644 --- a/source/Plugins/Process/Utility/DynamicRegisterInfo.cpp +++ b/source/Plugins/Process/Utility/DynamicRegisterInfo.cpp @@ -16,6 +16,9 @@ // Other libraries and framework includes // Project includes #include "lldb/Interpreter/Args.h" +#include "lldb/Core/RegularExpression.h" +#include "lldb/Core/StreamFile.h" +#include "lldb/DataFormatters/FormatManager.h" #ifndef LLDB_DISABLE_PYTHON #include "lldb/Interpreter/PythonDataObjects.h" @@ -29,18 +32,24 @@ DynamicRegisterInfo::DynamicRegisterInfo () : m_sets (), m_set_reg_nums (), m_set_names (), - m_reg_data_byte_size (0) + m_value_regs_map (), + m_invalidate_regs_map (), + m_reg_data_byte_size (0), + m_finalized (false) { } -DynamicRegisterInfo::DynamicRegisterInfo (const lldb_private::PythonDictionary &dict) : +DynamicRegisterInfo::DynamicRegisterInfo (const lldb_private::PythonDictionary &dict, ByteOrder byte_order) : m_regs (), m_sets (), m_set_reg_nums (), m_set_names (), - m_reg_data_byte_size (0) + m_value_regs_map (), + m_invalidate_regs_map (), + m_reg_data_byte_size (0), + m_finalized (false) { - SetRegisterInfo (dict); + SetRegisterInfo (dict, byte_order); } DynamicRegisterInfo::~DynamicRegisterInfo () @@ -49,8 +58,10 @@ DynamicRegisterInfo::~DynamicRegisterInfo () size_t -DynamicRegisterInfo::SetRegisterInfo (const lldb_private::PythonDictionary &dict) +DynamicRegisterInfo::SetRegisterInfo (const lldb_private::PythonDictionary &dict, + ByteOrder byte_order) { + assert(!m_finalized); #ifndef LLDB_DISABLE_PYTHON PythonList sets (dict.GetItemForKey("sets")); if (sets) @@ -89,6 +100,12 @@ DynamicRegisterInfo::SetRegisterInfo (const lldb_private::PythonDictionary &dict PythonString gcc_pystr("gcc"); PythonString dwarf_pystr("dwarf"); PythonString generic_pystr("generic"); + PythonString slice_pystr("slice"); + PythonString composite_pystr("composite"); + PythonString invalidate_regs_pystr("invalidate-regs"); + +// typedef std::map<std::string, std::vector<std::string> > InvalidateNameMap; +// InvalidateNameMap invalidate_map; for (uint32_t i=0; i<num_regs; ++i) { PythonDictionary reg_info_dict(regs.GetItemAtIndex(i)); @@ -96,6 +113,8 @@ DynamicRegisterInfo::SetRegisterInfo (const lldb_private::PythonDictionary &dict { // { 'name':'rcx' , 'bitsize' : 64, 'offset' : 16, 'encoding':'uint' , 'format':'hex' , 'set': 0, 'gcc' : 2, 'dwarf' : 2, 'generic':'arg4', 'alt-name':'arg4', }, RegisterInfo reg_info; + std::vector<uint32_t> value_regs; + std::vector<uint32_t> invalidate_regs; bzero (®_info, sizeof(reg_info)); reg_info.name = ConstString (reg_info_dict.GetItemForKeyAsString(name_pystr)).GetCString(); @@ -111,16 +130,177 @@ DynamicRegisterInfo::SetRegisterInfo (const lldb_private::PythonDictionary &dict if (reg_info.byte_offset == UINT32_MAX) { - Clear(); - return 0; + // No offset for this register, see if the register has a value expression + // which indicates this register is part of another register. Value expressions + // are things like "rax[31:0]" which state that the current register's value + // is in a concrete register "rax" in bits 31:0. If there is a value expression + // we can calculate the offset + bool success = false; + const char *slice_cstr = reg_info_dict.GetItemForKeyAsString(slice_pystr); + if (slice_cstr) + { + // Slices use the following format: + // REGNAME[MSBIT:LSBIT] + // REGNAME - name of the register to grab a slice of + // MSBIT - the most significant bit at which the current register value starts at + // LSBIT - the least significant bit at which the current register value ends at + static RegularExpression g_bitfield_regex("([A-Za-z_][A-Za-z0-9_]*)\\[([0-9]+):([0-9]+)\\]"); + RegularExpression::Match regex_match(3); + if (g_bitfield_regex.Execute(slice_cstr, ®ex_match)) + { + llvm::StringRef reg_name_str; + std::string msbit_str; + std::string lsbit_str; + if (regex_match.GetMatchAtIndex(slice_cstr, 1, reg_name_str) && + regex_match.GetMatchAtIndex(slice_cstr, 2, msbit_str) && + regex_match.GetMatchAtIndex(slice_cstr, 3, lsbit_str)) + { + const uint32_t msbit = Args::StringToUInt32(msbit_str.c_str(), UINT32_MAX); + const uint32_t lsbit = Args::StringToUInt32(lsbit_str.c_str(), UINT32_MAX); + if (msbit != UINT32_MAX && lsbit != UINT32_MAX) + { + if (msbit > lsbit) + { + const uint32_t msbyte = msbit / 8; + const uint32_t lsbyte = lsbit / 8; + + ConstString containing_reg_name(reg_name_str); + + RegisterInfo *containing_reg_info = GetRegisterInfo (containing_reg_name); + if (containing_reg_info) + { + const uint32_t max_bit = containing_reg_info->byte_size * 8; + if (msbit < max_bit && lsbit < max_bit) + { + m_invalidate_regs_map[containing_reg_info->kinds[eRegisterKindLLDB]].push_back(i); + m_value_regs_map[i].push_back(containing_reg_info->kinds[eRegisterKindLLDB]); + m_invalidate_regs_map[i].push_back(containing_reg_info->kinds[eRegisterKindLLDB]); + + if (byte_order == eByteOrderLittle) + { + success = true; + reg_info.byte_offset = containing_reg_info->byte_offset + lsbyte; + } + else if (byte_order == eByteOrderBig) + { + success = true; + reg_info.byte_offset = containing_reg_info->byte_offset + msbyte; + } + else + { + assert(!"Invalid byte order"); + } + } + else + { + if (msbit > max_bit) + printf("error: msbit (%u) must be less than the bitsize of the register (%u)\n", msbit, max_bit); + else + printf("error: lsbit (%u) must be less than the bitsize of the register (%u)\n", lsbit, max_bit); + } + } + else + { + printf("error: invalid concrete register \"%s\"\n", containing_reg_name.GetCString()); + } + } + else + { + printf("error: msbit (%u) must be greater than lsbit (%u)\n", msbit, lsbit); + } + } + else + { + printf("error: msbit (%u) and lsbit (%u) must be valid\n", msbit, lsbit); + } + } + else + { + // TODO: print error invalid slice string that doesn't follow the format + printf("error: failed to extract regex matches for parsing the register bitfield regex\n"); + + } + } + else + { + // TODO: print error invalid slice string that doesn't follow the format + printf("error: failed to match against register bitfield regex\n"); + } + } + else + { + PythonList composite_reg_list (reg_info_dict.GetItemForKey(composite_pystr)); + if (composite_reg_list) + { + const size_t num_composite_regs = composite_reg_list.GetSize(); + if (num_composite_regs > 0) + { + uint32_t composite_offset = UINT32_MAX; + for (uint32_t composite_idx=0; composite_idx<num_composite_regs; ++composite_idx) + { + PythonString composite_reg_name_pystr(composite_reg_list.GetItemAtIndex(composite_idx)); + if (composite_reg_name_pystr) + { + ConstString composite_reg_name(composite_reg_name_pystr.GetString()); + if (composite_reg_name) + { + RegisterInfo *composite_reg_info = GetRegisterInfo (composite_reg_name); + if (composite_reg_info) + { + if (composite_offset > composite_reg_info->byte_offset) + composite_offset = composite_reg_info->byte_offset; + m_value_regs_map[i].push_back(composite_reg_info->kinds[eRegisterKindLLDB]); + m_invalidate_regs_map[composite_reg_info->kinds[eRegisterKindLLDB]].push_back(i); + m_invalidate_regs_map[i].push_back(composite_reg_info->kinds[eRegisterKindLLDB]); + } + else + { + // TODO: print error invalid slice string that doesn't follow the format + printf("error: failed to find composite register by name: \"%s\"\n", composite_reg_name.GetCString()); + } + } + else + { + printf("error: 'composite' key contained an empty string\n"); + } + } + else + { + printf("error: 'composite' list value wasn't a python string\n"); + } + } + if (composite_offset != UINT32_MAX) + { + reg_info.byte_offset = composite_offset; + success = m_value_regs_map.find(i) != m_value_regs_map.end(); + } + else + { + printf("error: 'composite' registers must specify at least one real register\n"); + } + } + else + { + printf("error: 'composite' list was empty\n"); + } + } + } + + + if (!success) + { + Clear(); + return 0; + } } - reg_info.byte_size = reg_info_dict.GetItemForKeyAsInteger(bitsize_pystr, 0) / 8; - - if (reg_info.byte_size == 0) + const int64_t bitsize = reg_info_dict.GetItemForKeyAsInteger(bitsize_pystr, 0); + if (bitsize == 0) { Clear(); return 0; } + + reg_info.byte_size = bitsize / 8; const char *format_cstr = reg_info_dict.GetItemForKeyAsString(format_pystr); if (format_cstr) @@ -132,13 +312,15 @@ DynamicRegisterInfo::SetRegisterInfo (const lldb_private::PythonDictionary &dict } } else - reg_info.format = eFormatHex; - + { + reg_info.format = (Format)reg_info_dict.GetItemForKeyAsInteger (format_pystr, eFormatHex); + } + const char *encoding_cstr = reg_info_dict.GetItemForKeyAsString(encoding_pystr); if (encoding_cstr) reg_info.encoding = Args::StringToEncoding (encoding_cstr, eEncodingUint); else - reg_info.encoding = eEncodingUint; + reg_info.encoding = (Encoding)reg_info_dict.GetItemForKeyAsInteger (encoding_pystr, eEncodingUint); const int64_t set = reg_info_dict.GetItemForKeyAsInteger(set_pystr, -1); if (set >= m_sets.size()) @@ -147,11 +329,75 @@ DynamicRegisterInfo::SetRegisterInfo (const lldb_private::PythonDictionary &dict return 0; } + // Fill in the register numbers reg_info.kinds[lldb::eRegisterKindLLDB] = i; reg_info.kinds[lldb::eRegisterKindGDB] = i; reg_info.kinds[lldb::eRegisterKindGCC] = reg_info_dict.GetItemForKeyAsInteger(gcc_pystr, LLDB_INVALID_REGNUM); reg_info.kinds[lldb::eRegisterKindDWARF] = reg_info_dict.GetItemForKeyAsInteger(dwarf_pystr, LLDB_INVALID_REGNUM); - reg_info.kinds[lldb::eRegisterKindGeneric] = Args::StringToGenericRegister (reg_info_dict.GetItemForKeyAsString(generic_pystr)); + const char *generic_cstr = reg_info_dict.GetItemForKeyAsString(generic_pystr); + if (generic_cstr) + reg_info.kinds[lldb::eRegisterKindGeneric] = Args::StringToGenericRegister (generic_cstr); + else + reg_info.kinds[lldb::eRegisterKindGeneric] = reg_info_dict.GetItemForKeyAsInteger(generic_pystr, LLDB_INVALID_REGNUM); + + // Check if this register invalidates any other register values when it is modified + PythonList invalidate_reg_list (reg_info_dict.GetItemForKey(invalidate_regs_pystr)); + if (invalidate_reg_list) + { + const size_t num_regs = invalidate_reg_list.GetSize(); + if (num_regs > 0) + { + for (uint32_t idx=0; idx<num_regs; ++idx) + { + PythonObject invalidate_reg_object (invalidate_reg_list.GetItemAtIndex(idx)); + PythonString invalidate_reg_name_pystr(invalidate_reg_object); + if (invalidate_reg_name_pystr) + { + ConstString invalidate_reg_name(invalidate_reg_name_pystr.GetString()); + if (invalidate_reg_name) + { + RegisterInfo *invalidate_reg_info = GetRegisterInfo (invalidate_reg_name); + if (invalidate_reg_info) + { + m_invalidate_regs_map[i].push_back(invalidate_reg_info->kinds[eRegisterKindLLDB]); + } + else + { + // TODO: print error invalid slice string that doesn't follow the format + printf("error: failed to find a 'invalidate-regs' register for \"%s\" while parsing register \"%s\"\n", invalidate_reg_name.GetCString(), reg_info.name); + } + } + else + { + printf("error: 'invalidate-regs' list value was an empty string\n"); + } + } + else + { + PythonInteger invalidate_reg_num(invalidate_reg_object); + + if (invalidate_reg_num) + { + const int64_t r = invalidate_reg_num.GetInteger(); + if (r != UINT64_MAX) + m_invalidate_regs_map[i].push_back(r); + else + printf("error: 'invalidate-regs' list value wasn't a valid integer\n"); + } + else + { + printf("error: 'invalidate-regs' list value wasn't a python string or integer\n"); + } + } + } + } + else + { + printf("error: 'invalidate-regs' contained an empty list\n"); + } + } + + // Calculate the register offset const size_t end_reg_offset = reg_info.byte_offset + reg_info.byte_size; if (m_reg_data_byte_size < end_reg_offset) m_reg_data_byte_size = end_reg_offset; @@ -169,7 +415,7 @@ DynamicRegisterInfo::SetRegisterInfo (const lldb_private::PythonDictionary &dict Finalize (); } #endif - return 0; + return m_regs.size(); } @@ -179,10 +425,22 @@ DynamicRegisterInfo::AddRegister (RegisterInfo ®_info, ConstString ®_alt_name, ConstString &set_name) { + assert(!m_finalized); const uint32_t reg_num = m_regs.size(); reg_info.name = reg_name.AsCString(); assert (reg_info.name); reg_info.alt_name = reg_alt_name.AsCString(NULL); + uint32_t i; + if (reg_info.value_regs) + { + for (i=0; reg_info.value_regs[i] != LLDB_INVALID_REGNUM; ++i) + m_value_regs_map[reg_num].push_back(reg_info.value_regs[i]); + } + if (reg_info.invalidate_regs) + { + for (i=0; reg_info.invalidate_regs[i] != LLDB_INVALID_REGNUM; ++i) + m_invalidate_regs_map[reg_num].push_back(reg_info.invalidate_regs[i]); + } m_regs.push_back (reg_info); uint32_t set = GetRegisterSetIndexByName (set_name, true); assert (set < m_sets.size()); @@ -197,12 +455,99 @@ DynamicRegisterInfo::AddRegister (RegisterInfo ®_info, void DynamicRegisterInfo::Finalize () { - for (uint32_t set = 0; set < m_sets.size(); ++set) + if (m_finalized) + return; + + m_finalized = true; + const size_t num_sets = m_sets.size(); + for (size_t set = 0; set < num_sets; ++set) { assert (m_sets.size() == m_set_reg_nums.size()); m_sets[set].num_registers = m_set_reg_nums[set].size(); m_sets[set].registers = &m_set_reg_nums[set][0]; } + + // sort and unique all value registers and make sure each is terminated with + // LLDB_INVALID_REGNUM + + for (reg_to_regs_map::iterator pos = m_value_regs_map.begin(), end = m_value_regs_map.end(); + pos != end; + ++pos) + { + if (pos->second.size() > 1) + { + std::sort (pos->second.begin(), pos->second.end()); + reg_num_collection::iterator unique_end = std::unique (pos->second.begin(), pos->second.end()); + if (unique_end != pos->second.end()) + pos->second.erase(unique_end, pos->second.end()); + } + assert (!pos->second.empty()); + if (pos->second.back() != LLDB_INVALID_REGNUM) + pos->second.push_back(LLDB_INVALID_REGNUM); + } + + // Now update all value_regs with each register info as needed + const size_t num_regs = m_regs.size(); + for (size_t i=0; i<num_regs; ++i) + { + if (m_value_regs_map.find(i) != m_value_regs_map.end()) + m_regs[i].value_regs = m_value_regs_map[i].data(); + else + m_regs[i].value_regs = NULL; + } + + // Expand all invalidation dependencies + for (reg_to_regs_map::iterator pos = m_invalidate_regs_map.begin(), end = m_invalidate_regs_map.end(); + pos != end; + ++pos) + { + const uint32_t reg_num = pos->first; + + if (m_regs[reg_num].value_regs) + { + reg_num_collection extra_invalid_regs; + for (const uint32_t invalidate_reg_num : pos->second) + { + reg_to_regs_map::iterator invalidate_pos = m_invalidate_regs_map.find(invalidate_reg_num); + if (invalidate_pos != m_invalidate_regs_map.end()) + { + for (const uint32_t concrete_invalidate_reg_num : invalidate_pos->second) + { + if (concrete_invalidate_reg_num != reg_num) + extra_invalid_regs.push_back(concrete_invalidate_reg_num); + } + } + } + pos->second.insert(pos->second.end(), extra_invalid_regs.begin(), extra_invalid_regs.end()); + } + } + + // sort and unique all invalidate registers and make sure each is terminated with + // LLDB_INVALID_REGNUM + for (reg_to_regs_map::iterator pos = m_invalidate_regs_map.begin(), end = m_invalidate_regs_map.end(); + pos != end; + ++pos) + { + if (pos->second.size() > 1) + { + std::sort (pos->second.begin(), pos->second.end()); + reg_num_collection::iterator unique_end = std::unique (pos->second.begin(), pos->second.end()); + if (unique_end != pos->second.end()) + pos->second.erase(unique_end, pos->second.end()); + } + assert (!pos->second.empty()); + if (pos->second.back() != LLDB_INVALID_REGNUM) + pos->second.push_back(LLDB_INVALID_REGNUM); + } + + // Now update all invalidate_regs with each register info as needed + for (size_t i=0; i<num_regs; ++i) + { + if (m_invalidate_regs_map.find(i) != m_invalidate_regs_map.end()) + m_regs[i].invalidate_regs = m_invalidate_regs_map[i].data(); + else + m_regs[i].invalidate_regs = NULL; + } } size_t @@ -276,4 +621,83 @@ DynamicRegisterInfo::Clear() m_sets.clear(); m_set_reg_nums.clear(); m_set_names.clear(); + m_value_regs_map.clear(); + m_invalidate_regs_map.clear(); + m_reg_data_byte_size = 0; + m_finalized = false; +} + +void +DynamicRegisterInfo::Dump () const +{ + StreamFile s(stdout, false); + const size_t num_regs = m_regs.size(); + s.Printf("%p: DynamicRegisterInfo contains %zu registers:\n", this, num_regs); + for (size_t i=0; i<num_regs; ++i) + { + s.Printf("[%3zu] name = %-10s", i, m_regs[i].name); + s.Printf(", size = %2u, offset = %4u, encoding = %u, format = %-10s", + m_regs[i].byte_size, + m_regs[i].byte_offset, + m_regs[i].encoding, + FormatManager::GetFormatAsCString (m_regs[i].format)); + if (m_regs[i].kinds[eRegisterKindGDB] != LLDB_INVALID_REGNUM) + s.Printf(", gdb = %3u", m_regs[i].kinds[eRegisterKindGDB]); + if (m_regs[i].kinds[eRegisterKindDWARF] != LLDB_INVALID_REGNUM) + s.Printf(", dwarf = %3u", m_regs[i].kinds[eRegisterKindDWARF]); + if (m_regs[i].kinds[eRegisterKindGCC] != LLDB_INVALID_REGNUM) + s.Printf(", gcc = %3u", m_regs[i].kinds[eRegisterKindGCC]); + if (m_regs[i].kinds[eRegisterKindGeneric] != LLDB_INVALID_REGNUM) + s.Printf(", generic = %3u", m_regs[i].kinds[eRegisterKindGeneric]); + if (m_regs[i].alt_name) + s.Printf(", alt-name = %s", m_regs[i].alt_name); + if (m_regs[i].value_regs) + { + s.Printf(", value_regs = [ "); + for (size_t j=0; m_regs[i].value_regs[j] != LLDB_INVALID_REGNUM; ++j) + { + s.Printf("%s ", m_regs[m_regs[i].value_regs[j]].name); + } + s.Printf("]"); + } + if (m_regs[i].invalidate_regs) + { + s.Printf(", invalidate_regs = [ "); + for (size_t j=0; m_regs[i].invalidate_regs[j] != LLDB_INVALID_REGNUM; ++j) + { + s.Printf("%s ", m_regs[m_regs[i].invalidate_regs[j]].name); + } + s.Printf("]"); + } + s.EOL(); + } + + const size_t num_sets = m_sets.size(); + s.Printf("%p: DynamicRegisterInfo contains %zu register sets:\n", this, num_sets); + for (size_t i=0; i<num_sets; ++i) + { + s.Printf("set[%zu] name = %s, regs = [", i, m_sets[i].name); + for (size_t idx=0; idx<m_sets[i].num_registers; ++idx) + { + s.Printf("%s ", m_regs[m_sets[i].registers[idx]].name); + } + s.Printf("]\n"); + } +} + + + +lldb_private::RegisterInfo * +DynamicRegisterInfo::GetRegisterInfo (const lldb_private::ConstString ®_name) +{ + for (auto ®_info : m_regs) + { + // We can use pointer comparison since we used a ConstString to set + // the "name" member in AddRegister() + if (reg_info.name == reg_name.GetCString()) + { + return ®_info; + } + } + return NULL; } diff --git a/source/Plugins/Process/Utility/DynamicRegisterInfo.h b/source/Plugins/Process/Utility/DynamicRegisterInfo.h index a11cd33..a41c77e 100644 --- a/source/Plugins/Process/Utility/DynamicRegisterInfo.h +++ b/source/Plugins/Process/Utility/DynamicRegisterInfo.h @@ -13,6 +13,7 @@ // C Includes // C++ Includes #include <vector> +#include <map> // Other libraries and framework includes // Project includes @@ -24,13 +25,15 @@ class DynamicRegisterInfo public: DynamicRegisterInfo (); - DynamicRegisterInfo (const lldb_private::PythonDictionary &dict); + DynamicRegisterInfo (const lldb_private::PythonDictionary &dict, + lldb::ByteOrder byte_order); virtual ~DynamicRegisterInfo (); size_t - SetRegisterInfo (const lldb_private::PythonDictionary &dict); + SetRegisterInfo (const lldb_private::PythonDictionary &dict, + lldb::ByteOrder byte_order); void AddRegister (lldb_private::RegisterInfo ®_info, @@ -63,6 +66,9 @@ public: ConvertRegisterKindToRegisterNumber (uint32_t kind, uint32_t num) const; void + Dump () const; + + void Clear(); protected: @@ -74,12 +80,19 @@ protected: typedef std::vector <uint32_t> reg_num_collection; typedef std::vector <reg_num_collection> set_reg_num_collection; typedef std::vector <lldb_private::ConstString> name_collection; + typedef std::map<uint32_t, reg_num_collection> reg_to_regs_map; + + lldb_private::RegisterInfo * + GetRegisterInfo (const lldb_private::ConstString ®_name); reg_collection m_regs; set_collection m_sets; set_reg_num_collection m_set_reg_nums; name_collection m_set_names; + reg_to_regs_map m_value_regs_map; + reg_to_regs_map m_invalidate_regs_map; size_t m_reg_data_byte_size; // The number of bytes required to store all registers + bool m_finalized; }; #endif // lldb_DynamicRegisterInfo_h_ diff --git a/source/Plugins/Process/Utility/InferiorCallPOSIX.cpp b/source/Plugins/Process/Utility/InferiorCallPOSIX.cpp index 499d6d7..8b22d64 100644 --- a/source/Plugins/Process/Utility/InferiorCallPOSIX.cpp +++ b/source/Plugins/Process/Utility/InferiorCallPOSIX.cpp @@ -17,8 +17,19 @@ #include "lldb/Target/Process.h" #include "lldb/Target/Target.h" #include "lldb/Target/ThreadPlanCallFunction.h" +#include "lldb/Host/Config.h" +#ifndef LLDB_DISABLE_POSIX #include <sys/mman.h> +#else +// define them +#define PROT_NONE 0 +#define PROT_READ 1 +#define PROT_WRITE 2 +#define PROT_EXEC 4 +#define MAP_PRIVATE 2 +#define MAP_ANON 0x1000 +#endif using namespace lldb; using namespace lldb_private; diff --git a/source/Plugins/Process/Utility/RegisterContextLLDB.cpp b/source/Plugins/Process/Utility/RegisterContextLLDB.cpp index 1ffc30d..c19aec3 100644 --- a/source/Plugins/Process/Utility/RegisterContextLLDB.cpp +++ b/source/Plugins/Process/Utility/RegisterContextLLDB.cpp @@ -369,8 +369,13 @@ RegisterContextLLDB::InitializeNonZerothFrame() return; } + bool resolve_tail_call_address = true; // m_current_pc can be one past the address range of the function... + uint32_t resolved_scope = pc_module_sp->ResolveSymbolContextForAddress (m_current_pc, + eSymbolContextFunction | eSymbolContextSymbol, + m_sym_ctx, resolve_tail_call_address); + // We require that eSymbolContextSymbol be successfully filled in or this context is of no use to us. - if ((pc_module_sp->ResolveSymbolContextForAddress (m_current_pc, eSymbolContextFunction| eSymbolContextSymbol, m_sym_ctx) & eSymbolContextSymbol) == eSymbolContextSymbol) + if ((resolved_scope & eSymbolContextSymbol) == eSymbolContextSymbol) { m_sym_ctx_valid = true; } @@ -387,35 +392,18 @@ RegisterContextLLDB::InitializeNonZerothFrame() if (m_sym_ctx_valid == false) decr_pc_and_recompute_addr_range = true; - // Or if we're in the middle of the stack (and not "above" an asynchronous event like sigtramp), - // and our "current" pc is the start of a function... + // Or if we're in the middle of the stack (and not "above" an asynchronous event like sigtramp), and + // our "current" pc is the start of a function or our "current" pc is one past the end of a function... if (m_sym_ctx_valid && GetNextFrame()->m_frame_type != eSigtrampFrame && GetNextFrame()->m_frame_type != eDebuggerFrame && addr_range.GetBaseAddress().IsValid() - && addr_range.GetBaseAddress().GetSection() == m_current_pc.GetSection() - && addr_range.GetBaseAddress().GetOffset() == m_current_pc.GetOffset()) + && addr_range.GetBaseAddress().GetSection() == m_current_pc.GetSection()) { - decr_pc_and_recompute_addr_range = true; - } - - // We need to back up the pc by 1 byte and re-search for the Symbol to handle the case where the "saved pc" - // value is pointing to the next function, e.g. if a function ends with a CALL instruction. - // FIXME this may need to be an architectural-dependent behavior; if so we'll need to add a member function - // to the ABI plugin and consult that. - if (decr_pc_and_recompute_addr_range) - { - Address temporary_pc(m_current_pc); - temporary_pc.SetOffset(m_current_pc.GetOffset() - 1); - m_sym_ctx.Clear(false); - m_sym_ctx_valid = false; - if ((pc_module_sp->ResolveSymbolContextForAddress (temporary_pc, eSymbolContextFunction| eSymbolContextSymbol, m_sym_ctx) & eSymbolContextSymbol) == eSymbolContextSymbol) + if (addr_range.GetBaseAddress().GetOffset() == m_current_pc.GetOffset() || + addr_range.GetBaseAddress().GetOffset() + addr_range.GetByteSize() == m_current_pc.GetOffset()) { - m_sym_ctx_valid = true; - } - if (!m_sym_ctx.GetAddressRange (eSymbolContextFunction | eSymbolContextSymbol, 0, false, addr_range)) - { - m_sym_ctx_valid = false; + decr_pc_and_recompute_addr_range = true; } } @@ -632,6 +620,10 @@ RegisterContextLLDB::GetFullUnwindPlanForFrame () arch_default_unwind_plan_sp.reset (new UnwindPlan (lldb::eRegisterKindGeneric)); abi->CreateDefaultUnwindPlan(*arch_default_unwind_plan_sp); } + else + { + UnwindLogMsg ("unable to get architectural default UnwindPlan from ABI plugin"); + } bool behaves_like_zeroth_frame = false; if (IsFrameZero () @@ -648,9 +640,10 @@ RegisterContextLLDB::GetFullUnwindPlanForFrame () // in the zeroth frame, we need to use the "unwind at first instruction" arch default UnwindPlan // Also, if this Process can report on memory region attributes, any non-executable region means // we jumped through a bad function pointer - handle the same way as 0x0. - // Note, if the symbol context has a function for the symbol, then we don't need to do this check. + // Note, if we have a symbol context & a symbol, we don't want to follow this code path. This is + // for jumping to memory regions without any information available. - if ((!m_sym_ctx_valid || m_sym_ctx.function == NULL) && behaves_like_zeroth_frame && m_current_pc.IsValid()) + if ((!m_sym_ctx_valid || m_sym_ctx.symbol == NULL) && behaves_like_zeroth_frame && m_current_pc.IsValid()) { uint32_t permissions; addr_t current_pc_addr = m_current_pc.GetLoadAddress (exe_ctx.GetTargetPtr()); @@ -757,8 +750,24 @@ RegisterContextLLDB::GetFullUnwindPlanForFrame () return unwind_plan_sp; } + // If we're on the first instruction of a function, and we have an architectural default UnwindPlan + // for the initial instruction of a function, use that. + if (m_current_offset_backed_up_one == 0) + { + unwind_plan_sp = func_unwinders_sp->GetUnwindPlanArchitectureDefaultAtFunctionEntry (m_thread); + if (unwind_plan_sp) + { + UnwindLogMsgVerbose ("frame uses %s for full UnwindPlan", unwind_plan_sp->GetSourceName().GetCString()); + return unwind_plan_sp; + } + } + // If nothing else, use the architectural default UnwindPlan and hope that does the job. - UnwindLogMsgVerbose ("frame uses %s for full UnwindPlan", arch_default_unwind_plan_sp->GetSourceName().GetCString()); + if (arch_default_unwind_plan_sp) + UnwindLogMsgVerbose ("frame uses %s for full UnwindPlan", arch_default_unwind_plan_sp->GetSourceName().GetCString()); + else + UnwindLogMsg ("Unable to find any UnwindPlan for full unwind of this frame."); + return arch_default_unwind_plan_sp; } @@ -1101,7 +1110,8 @@ RegisterContextLLDB::SavedLocationForRegister (uint32_t lldb_regnum, lldb_privat const RegisterInfo *reg_info = GetRegisterInfoAtIndex(lldb_regnum); if (reg_info && abi->RegisterIsVolatile (reg_info)) { - UnwindLogMsg ("did not supply reg location for %d because it is volatile", lldb_regnum); + UnwindLogMsg ("did not supply reg location for %d (%s) because it is volatile", + lldb_regnum, reg_info->name ? reg_info->name : "??"); return UnwindLLDB::RegisterSearchResult::eRegisterIsVolatile; } } @@ -1186,7 +1196,8 @@ RegisterContextLLDB::SavedLocationForRegister (uint32_t lldb_regnum, lldb_privat DataExtractor dwarfdata (unwindplan_regloc.GetDWARFExpressionBytes(), unwindplan_regloc.GetDWARFExpressionLength(), process->GetByteOrder(), process->GetAddressByteSize()); - DWARFExpression dwarfexpr (dwarfdata, 0, unwindplan_regloc.GetDWARFExpressionLength()); + ModuleSP opcode_ctx; + DWARFExpression dwarfexpr (opcode_ctx, dwarfdata, 0, unwindplan_regloc.GetDWARFExpressionLength()); dwarfexpr.SetRegisterKind (unwindplan_registerkind); Value result; Error error; diff --git a/source/Plugins/Process/Utility/RegisterContextMacOSXFrameBackchain.cpp b/source/Plugins/Process/Utility/RegisterContextMacOSXFrameBackchain.cpp index 2c3eee4..5b6d9fe 100644 --- a/source/Plugins/Process/Utility/RegisterContextMacOSXFrameBackchain.cpp +++ b/source/Plugins/Process/Utility/RegisterContextMacOSXFrameBackchain.cpp @@ -147,9 +147,9 @@ RegisterContextMacOSXFrameBackchain::ReadRegister (const RegisterInfo *reg_info, } break; - // TOOD: need a better way to detect when "long double" types are + // TOOD: need a better way to detect when "long double" types are // the same bytes size as "double" -#if !defined(__arm__) +#if !defined(__arm__) && !defined(_MSC_VER) && !defined(__mips__) case sizeof (long double): if (sizeof (long double) == sizeof(uint32_t)) { diff --git a/source/Plugins/Process/Utility/UnwindLLDB.cpp b/source/Plugins/Process/Utility/UnwindLLDB.cpp index 0eea003..552ae50 100644 --- a/source/Plugins/Process/Utility/UnwindLLDB.cpp +++ b/source/Plugins/Process/Utility/UnwindLLDB.cpp @@ -185,21 +185,7 @@ UnwindLLDB::AddOneMoreFrame (ABI *abi) } goto unwind_done; } - if (!m_frames.empty()) - { - if (m_frames.back()->start_pc == cursor_sp->start_pc) - { - if (m_frames.back()->cfa == cursor_sp->cfa) - goto unwind_done; // Infinite loop where the current cursor is the same as the previous one... - else if (abi && abi->StackUsesFrames()) - { - // We might have a CFA that is not using the frame pointer and - // we want to validate that the frame pointer is valid. - if (reg_ctx_sp->GetFP() == 0) - goto unwind_done; - } - } - } + cursor_sp->reg_ctx_lldb_sp = reg_ctx_sp; m_frames.push_back (cursor_sp); return true; |