diff options
Diffstat (limited to 'contrib/llvm-project/lldb')
564 files changed, 19414 insertions, 11761 deletions
diff --git a/contrib/llvm-project/lldb/bindings/interface/SBDebugger.i b/contrib/llvm-project/lldb/bindings/interface/SBDebugger.i index cf4411980cc3..aae72dd51394 100644 --- a/contrib/llvm-project/lldb/bindings/interface/SBDebugger.i +++ b/contrib/llvm-project/lldb/bindings/interface/SBDebugger.i @@ -479,6 +479,8 @@ public: lldb::SBTypeSynthetic GetSyntheticForType (lldb::SBTypeNameSpecifier); + SBStructuredData GetScriptInterpreterInfo(ScriptLanguage); + STRING_EXTENSION(SBDebugger) %feature("docstring", diff --git a/contrib/llvm-project/lldb/bindings/interface/SBMemoryRegionInfo.i b/contrib/llvm-project/lldb/bindings/interface/SBMemoryRegionInfo.i index 3460dc0d06e2..0316c5a5be1d 100644 --- a/contrib/llvm-project/lldb/bindings/interface/SBMemoryRegionInfo.i +++ b/contrib/llvm-project/lldb/bindings/interface/SBMemoryRegionInfo.i @@ -20,6 +20,9 @@ public: SBMemoryRegionInfo (const lldb::SBMemoryRegionInfo &rhs); + SBMemoryRegionInfo::SBMemoryRegionInfo(const char *name, lldb::addr_t begin, + lldb::addr_t end, uint32_t permissions, bool mapped, bool stack_memory); + ~SBMemoryRegionInfo (); void diff --git a/contrib/llvm-project/lldb/bindings/interface/SBMemoryRegionInfoList.i b/contrib/llvm-project/lldb/bindings/interface/SBMemoryRegionInfoList.i index c2e74f1cd0dc..009751277542 100644 --- a/contrib/llvm-project/lldb/bindings/interface/SBMemoryRegionInfoList.i +++ b/contrib/llvm-project/lldb/bindings/interface/SBMemoryRegionInfoList.i @@ -25,6 +25,9 @@ public: GetSize () const; bool + GetMemoryRegionContainingAddress (lldb::addr_t addr, SBMemoryRegionInfo ®ion_info); + + bool GetMemoryRegionAtIndex (uint32_t idx, SBMemoryRegionInfo ®ion_info); void diff --git a/contrib/llvm-project/lldb/bindings/interface/SBSymbolContextList.i b/contrib/llvm-project/lldb/bindings/interface/SBSymbolContextList.i index e9d4aa8d62db..14566b3e3720 100644 --- a/contrib/llvm-project/lldb/bindings/interface/SBSymbolContextList.i +++ b/contrib/llvm-project/lldb/bindings/interface/SBSymbolContextList.i @@ -14,7 +14,7 @@ namespace lldb { For example (from test/python_api/target/TestTargetAPI.py), :: def find_functions(self, exe_name): - '''Exercise SBTaget.FindFunctions() API.''' + '''Exercise SBTarget.FindFunctions() API.''' exe = os.path.join(os.getcwd(), exe_name) # Create a target by the debugger. diff --git a/contrib/llvm-project/lldb/bindings/interface/SBType.i b/contrib/llvm-project/lldb/bindings/interface/SBType.i index 500bc99ca8cd..d6e8db3ab428 100644 --- a/contrib/llvm-project/lldb/bindings/interface/SBType.i +++ b/contrib/llvm-project/lldb/bindings/interface/SBType.i @@ -837,6 +837,21 @@ public: lldb::SBTypeMemberFunction GetMemberFunctionAtIndex (uint32_t idx); + %feature("docstring", + "Returns true if the type is completely defined. + + Language-specific behaviour: + + * C: Returns false for struct types that were only forward declared in the + type's `SBTarget`/`SBModule`. Otherwise returns true. + * C++: Returns false for template/non-template struct/class types and + scoped enums that were only forward declared inside the type's + `SBTarget`/`SBModule`. Otherwise returns true. + * Objective-C: Follows the same behavior as C for struct types. Objective-C + classes are considered complete unless they were only forward declared via + ``@class ClassName`` in the type's `SBTarget`/`SBModule`. Otherwise + returns true. + ") IsTypeComplete; bool IsTypeComplete (); diff --git a/contrib/llvm-project/lldb/bindings/lua/lua-typemaps.swig b/contrib/llvm-project/lldb/bindings/lua/lua-typemaps.swig index d912137a5674..e3b3f5718d15 100644 --- a/contrib/llvm-project/lldb/bindings/lua/lua-typemaps.swig +++ b/contrib/llvm-project/lldb/bindings/lua/lua-typemaps.swig @@ -12,7 +12,7 @@ // Primitive integer mapping %typemap(in,checkfn="lua_isinteger") TYPE -%{ $1 = (TYPE)lua_tointeger(L, $input); %} +%{ $1 = ($type)lua_tointeger(L, $input); %} %typemap(in,checkfn="lua_isinteger") const TYPE&($basetype temp) %{ temp=($basetype)lua_tointeger(L,$input); $1=&temp;%} %typemap(out) TYPE @@ -54,6 +54,7 @@ LLDB_NUMBER_TYPEMAP(signed long); LLDB_NUMBER_TYPEMAP(long long); LLDB_NUMBER_TYPEMAP(unsigned long long); LLDB_NUMBER_TYPEMAP(signed long long); +LLDB_NUMBER_TYPEMAP(enum SWIGTYPE); %apply unsigned long { size_t }; %apply const unsigned long & { const size_t & }; @@ -77,7 +78,7 @@ LLDB_NUMBER_TYPEMAP(signed long long); %typemap(in) (char *dst, size_t dst_len) { $2 = luaL_checkinteger(L, $input); if ($2 <= 0) { - return luaL_error(L, "Positive integer expected"); + return luaL_error(L, "Positive integer expected"); } $1 = (char *) malloc($2); } @@ -86,6 +87,9 @@ LLDB_NUMBER_TYPEMAP(signed long long); // as char data instead of byte data. %typemap(in) (void *char_buf, size_t size) = (char *dst, size_t dst_len); +// Also SBProcess::ReadMemory. +%typemap(in) (void *buf, size_t size) = (char *dst, size_t dst_len); + // Return the char buffer. Discarding any previous return result %typemap(argout) (char *dst, size_t dst_len) { lua_pop(L, 1); // Blow away the previous result @@ -102,4 +106,211 @@ LLDB_NUMBER_TYPEMAP(signed long long); // as char data instead of byte data. %typemap(argout) (void *char_buf, size_t size) = (char *dst, size_t dst_len); +// Also SBProcess::ReadMemory. +%typemap(argout) (void *buf, size_t size) = (char *dst, size_t dst_len); + +//===----------------------------------------------------------------------===// + +// Typemap for handling a snprintf-like API like SBThread::GetStopDescription. + +%typemap(in) (char *dst_or_null, size_t dst_len) { + $2 = luaL_checkinteger(L, $input); + if ($2 <= 0) { + return luaL_error(L, "Positive integer expected"); + } + $1 = (char *)malloc($2); +} + +%typemap(argout) (char *dst_or_null, size_t dst_len) { + lua_pop(L, 1); // Blow away the previous result + lua_pushlstring(L, (const char *)$1, $result); + free($1); + // SWIG_arg was already incremented +} + +//===----------------------------------------------------------------------===// + +// Typemap for handling SBModule::GetVersion + +%typemap(in) (uint32_t *versions, uint32_t num_versions) { + $2 = 99; + $1 = (uint32_t *)malloc(sizeof(uint32_t) * $2); +} + +%typemap(argout) (uint32_t *versions, uint32_t num_versions) { + uint32_t count = result; + if (count >= $2) + count = $2; + lua_newtable(L); + int i = 0; + while (i++ < count) { + lua_pushinteger(L, $1[i - 1]); + lua_seti(L, -2, i); + } + SWIG_arg++; + free($1); +} + +//===----------------------------------------------------------------------===// + +// Typemap for handling SBDebugger::SetLoggingCallback + +%typemap(in) (lldb::LogOutputCallback log_callback, void *baton) { + $1 = LLDBSwigLuaCallLuaLogOutputCallback; + $2 = (void *)L; + + luaL_checktype(L, 2, LUA_TFUNCTION); + lua_settop(L, 2); + + lua_pushlightuserdata(L, (void *)&LLDBSwigLuaCallLuaLogOutputCallback); + lua_insert(L, 2); + lua_settable(L, LUA_REGISTRYINDEX); +} + +//===----------------------------------------------------------------------===// + +// Typemap for handling SBEvent::SBEvent(uint32_t event, const char *cstr, uint32_t cstr_len) + +%typemap(in) (const char *cstr, uint32_t cstr_len) { + $1 = (char *)luaL_checklstring(L, $input, (size_t *)&$2); +} + +// Typemap for handling SBProcess::PutSTDIN + +%typemap(in) (const char *src, size_t src_len) { + $1 = (char *)luaL_checklstring(L, $input, &$2); +} + +// Typemap for handling SBProcess::WriteMemory, SBTarget::GetInstructions... + +%typemap(in) (const void *buf, size_t size), + (const void *data, size_t data_len) { + $1 = (void *)luaL_checklstring(L, $input, &$2); +} + +//===----------------------------------------------------------------------===// + +// Typemap for handling char ** in SBTarget::LaunchSimple, SBTarget::Launch... + +// It should accept a Lua table of strings, for stuff like "argv" and "envp". + +%typemap(in) char ** { + if (lua_istable(L, $input)) { + size_t size = lua_rawlen(L, $input); + $1 = (char **)malloc((size + 1) * sizeof(char *)); + int i = 0, j = 0; + while (i++ < size) { + lua_rawgeti(L, $input, i); + if (!lua_isstring(L, -1)) { + // if current element cannot be converted to string, raise an error + lua_pop(L, 1); + return luaL_error(L, "List should only contain strings"); + } + $1[j++] = (char *)lua_tostring(L, -1); + lua_pop(L, 1); + } + $1[j] = 0; + } else if (lua_isnil(L, $input)) { + // "nil" is also acceptable, equivalent as an empty table + $1 = NULL; + } else { + return luaL_error(L, "A list of strings expected"); + } +} + +%typemap(freearg) char ** { + free((char *) $1); +} + +%typecheck(SWIG_TYPECHECK_STRING_ARRAY) char ** { + $1 = (lua_istable(L, $input) || lua_isnil(L, $input)); +} + +//===----------------------------------------------------------------------===// + +// Typemap for file handles (e.g. used in SBDebugger::SetOutputFile) + +%typemap(in) lldb::FileSP { + luaL_Stream *p = (luaL_Stream *)luaL_checkudata(L, $input, LUA_FILEHANDLE); + lldb::FileSP file_sp; + file_sp = std::make_shared<lldb_private::NativeFile>(p->f, false); + if (!file_sp->IsValid()) + return luaL_error(L, "Invalid file"); + $1 = file_sp; +} + +%typecheck(SWIG_TYPECHECK_POINTER) lldb::FileSP { + $1 = (lua_isuserdata(L, $input)) && + (luaL_testudata(L, $input, LUA_FILEHANDLE) != nullptr); +} + +// Typemap for file handles (e.g. used in SBDebugger::GetOutputFileHandle) + +%typemap(out) lldb::FileSP { + lldb::FileSP &sp = $1; + if (sp && sp->IsValid()) { + luaL_Stream *p = (luaL_Stream *)lua_newuserdata(L, sizeof(luaL_Stream)); + p->closef = &LLDBSwigLuaCloseFileHandle; + p->f = sp->GetStream(); + luaL_setmetatable(L, LUA_FILEHANDLE); + SWIG_arg++; + } +} + +//===----------------------------------------------------------------------===// + +// Typemap for SBData::CreateDataFromUInt64Array, SBData::SetDataFromUInt64Array ... + +%typemap(in) (uint64_t* array, size_t array_len), + (uint32_t* array, size_t array_len), + (int64_t* array, size_t array_len), + (int32_t* array, size_t array_len), + (double* array, size_t array_len) { + if (lua_istable(L, $input)) { + // It should accept a table of numbers. + $2 = lua_rawlen(L, $input); + $1 = ($1_ltype)malloc(($2) * sizeof($*1_type)); + int i = 0, j = 0; + while (i++ < $2) { + lua_rawgeti(L, $input, i); + if (!lua_isnumber(L, -1)) { + // if current element cannot be converted to number, raise an error + lua_pop(L, 1); + return luaL_error(L, "List should only contain numbers"); + } + $1[j++] = ($*1_ltype)lua_tonumber(L, -1); + lua_pop(L, 1); + } + } else if (lua_isnil(L, $input)) { + // "nil" is also acceptable, equivalent as an empty table + $1 = NULL; + $2 = 0; + } else { + // else raise an error + return luaL_error(L, "A list of numbers expected."); + } +} + +%typemap(freearg) (uint64_t* array, size_t array_len), + (uint32_t* array, size_t array_len), + (int64_t* array, size_t array_len), + (int32_t* array, size_t array_len), + (double* array, size_t array_len) { + free($1); +} + +//===----------------------------------------------------------------------===// + +// Typemap for SBCommandReturnObject::PutCString + +%typemap(in) (const char *string, int len) { + if (lua_isnil(L, $input)) { + $1 = NULL; + $2 = 0; + } + else { + $1 = (char *)luaL_checklstring(L, $input, (size_t *)&$2); + } +} + //===----------------------------------------------------------------------===// diff --git a/contrib/llvm-project/lldb/bindings/lua/lua-wrapper.swig b/contrib/llvm-project/lldb/bindings/lua/lua-wrapper.swig index e070bae23683..c51911bb6bf7 100644 --- a/contrib/llvm-project/lldb/bindings/lua/lua-wrapper.swig +++ b/contrib/llvm-project/lldb/bindings/lua/lua-wrapper.swig @@ -6,6 +6,19 @@ PushSBClass(lua_State* L, T* obj); %} +%runtime %{ +#ifdef __cplusplus +extern "C" { +#endif + +void LLDBSwigLuaCallLuaLogOutputCallback(const char *str, void *baton); +int LLDBSwigLuaCloseFileHandle(lua_State *L); + +#ifdef __cplusplus +} +#endif +%} + %wrapper %{ // This function is called from Lua::CallBreakpointCallback @@ -88,5 +101,20 @@ LLDBSwigLuaWatchpointCallbackFunction return stop; } +SWIGEXPORT void +LLDBSwigLuaCallLuaLogOutputCallback(const char *str, void *baton) { + lua_State *L = (lua_State *)baton; + + lua_pushlightuserdata(L, (void *)&LLDBSwigLuaCallLuaLogOutputCallback); + lua_gettable(L, LUA_REGISTRYINDEX); + + // FIXME: There's no way to report errors back to the user + lua_pushstring(L, str); + lua_pcall(L, 1, 0, 0); +} + +int LLDBSwigLuaCloseFileHandle(lua_State *L) { + return luaL_error(L, "You cannot close a file handle used by lldb."); +} %} diff --git a/contrib/llvm-project/lldb/bindings/lua/lua.swig b/contrib/llvm-project/lldb/bindings/lua/lua.swig index c702e4964081..21fa44c8b4d8 100644 --- a/contrib/llvm-project/lldb/bindings/lua/lua.swig +++ b/contrib/llvm-project/lldb/bindings/lua/lua.swig @@ -17,6 +17,10 @@ #include "llvm/Support/Error.h" #include "llvm/Support/FormatVariadic.h" #include "../bindings/lua/lua-swigsafecast.swig" + +// required headers for typemaps +#include "lldb/Host/File.h" + using namespace lldb_private; using namespace lldb; %} diff --git a/contrib/llvm-project/lldb/bindings/python/lldb-python b/contrib/llvm-project/lldb/bindings/python/lldb-python new file mode 100755 index 000000000000..3bb3b332d852 --- /dev/null +++ b/contrib/llvm-project/lldb/bindings/python/lldb-python @@ -0,0 +1,17 @@ +#!/usr/bin/env python3 + +import subprocess +import os +import sys +import json + +lldb = os.path.join(os.path.dirname(__file__), 'lldb') + +info_json = subprocess.run([lldb, "-l", "python", "-print-script-interpreter-info"], + check=True, stdout=subprocess.PIPE, encoding='utf8').stdout +info = json.loads(info_json) + +os.environ["PYTHONPATH"] = ( + info["lldb-pythonpath"] + os.path.pathsep + os.environ.get("PYTHONPATH", "")) + +os.execl(info["executable"], info["executable"], *sys.argv[1:]) diff --git a/contrib/llvm-project/lldb/bindings/python/python-swigsafecast.swig b/contrib/llvm-project/lldb/bindings/python/python-swigsafecast.swig index 091fc29b1057..aa2bcfb8c8ae 100644 --- a/contrib/llvm-project/lldb/bindings/python/python-swigsafecast.swig +++ b/contrib/llvm-project/lldb/bindings/python/python-swigsafecast.swig @@ -1,161 +1,72 @@ -// leaving this undefined ensures we will get a linker error if we try to use SBTypeToSWIGWrapper() -// for a type for which we did not specialze this function -template <typename SBClass> -PyObject* -SBTypeToSWIGWrapper (SBClass* sb_object); - -template <typename SBClass> -PyObject* -SBTypeToSWIGWrapper (SBClass& sb_object) -{ - return SBTypeToSWIGWrapper(&sb_object); -} - -template <typename SBClass> -PyObject* -SBTypeToSWIGWrapper (const SBClass& sb_object) -{ - return SBTypeToSWIGWrapper(&sb_object); -} - -template <> -PyObject* -SBTypeToSWIGWrapper (PyObject* py_object) -{ - return py_object; -} - -template <> -PyObject* -SBTypeToSWIGWrapper (unsigned int* c_int) -{ - if (!c_int) - return NULL; - return PyInt_FromLong(*c_int); -} - -template <> -PyObject* -SBTypeToSWIGWrapper (lldb::SBEvent* event_sb) -{ - return SWIG_NewPointerObj((void *) event_sb, SWIGTYPE_p_lldb__SBEvent, 0); -} - -template <> -PyObject* -SBTypeToSWIGWrapper (lldb::SBProcess* process_sb) -{ - return SWIG_NewPointerObj((void *) process_sb, SWIGTYPE_p_lldb__SBProcess, 0); +PyObject *SBTypeToSWIGWrapper(lldb::SBEvent &event_sb) { + return SWIG_NewPointerObj(&event_sb, SWIGTYPE_p_lldb__SBEvent, 0); } -template <> -PyObject* -SBTypeToSWIGWrapper (lldb::SBThread* thread_sb) -{ - return SWIG_NewPointerObj((void *) thread_sb, SWIGTYPE_p_lldb__SBThread, 0); +PyObject *SBTypeToSWIGWrapper(lldb::SBProcess &process_sb) { + return SWIG_NewPointerObj(&process_sb, SWIGTYPE_p_lldb__SBProcess, 0); } -template <> -PyObject* -SBTypeToSWIGWrapper (lldb::SBThreadPlan* thread_plan_sb) -{ - return SWIG_NewPointerObj((void *) thread_plan_sb, SWIGTYPE_p_lldb__SBThreadPlan, 0); +PyObject *SBTypeToSWIGWrapper(lldb::SBThread &thread_sb) { + return SWIG_NewPointerObj(&thread_sb, SWIGTYPE_p_lldb__SBThread, 0); } -template <> -PyObject* -SBTypeToSWIGWrapper (lldb::SBTarget* target_sb) -{ - return SWIG_NewPointerObj((void *) target_sb, SWIGTYPE_p_lldb__SBTarget, 0); +PyObject *SBTypeToSWIGWrapper(lldb::SBThreadPlan &thread_plan_sb) { + return SWIG_NewPointerObj(&thread_plan_sb, SWIGTYPE_p_lldb__SBThreadPlan, 0); } -template <> -PyObject* -SBTypeToSWIGWrapper (lldb::SBFrame* frame_sb) -{ - return SWIG_NewPointerObj((void *) frame_sb, SWIGTYPE_p_lldb__SBFrame, 0); +PyObject *SBTypeToSWIGWrapper(lldb::SBTarget &target_sb) { + return SWIG_NewPointerObj(&target_sb, SWIGTYPE_p_lldb__SBTarget, 0); } -template <> -PyObject* -SBTypeToSWIGWrapper (lldb::SBDebugger* debugger_sb) -{ - return SWIG_NewPointerObj((void *) debugger_sb, SWIGTYPE_p_lldb__SBDebugger, 0); +PyObject *SBTypeToSWIGWrapper(lldb::SBFrame &frame_sb) { + return SWIG_NewPointerObj(&frame_sb, SWIGTYPE_p_lldb__SBFrame, 0); } -template <> -PyObject* -SBTypeToSWIGWrapper (lldb::SBBreakpoint* breakpoint_sb) -{ - return SWIG_NewPointerObj((void *) breakpoint_sb, SWIGTYPE_p_lldb__SBBreakpoint, 0); +PyObject *SBTypeToSWIGWrapper(lldb::SBDebugger &debugger_sb) { + return SWIG_NewPointerObj(&debugger_sb, SWIGTYPE_p_lldb__SBDebugger, 0); } -template <> -PyObject* -SBTypeToSWIGWrapper (lldb::SBWatchpoint* watchpoint_sb) -{ - return SWIG_NewPointerObj((void *) watchpoint_sb, SWIGTYPE_p_lldb__SBWatchpoint, 0); +PyObject *SBTypeToSWIGWrapper(lldb::SBBreakpoint &breakpoint_sb) { + return SWIG_NewPointerObj(&breakpoint_sb, SWIGTYPE_p_lldb__SBBreakpoint, 0); } -template <> -PyObject* -SBTypeToSWIGWrapper (lldb::SBBreakpointLocation* breakpoint_location_sb) -{ - return SWIG_NewPointerObj((void *) breakpoint_location_sb, SWIGTYPE_p_lldb__SBBreakpointLocation, 0); +PyObject *SBTypeToSWIGWrapper(lldb::SBWatchpoint &watchpoint_sb) { + return SWIG_NewPointerObj(&watchpoint_sb, SWIGTYPE_p_lldb__SBWatchpoint, 0); } -template <> -PyObject* -SBTypeToSWIGWrapper (lldb::SBBreakpointName* breakpoint_name_sb) -{ - return SWIG_NewPointerObj((void *) breakpoint_name_sb, SWIGTYPE_p_lldb__SBBreakpointName, 0); +PyObject * +SBTypeToSWIGWrapper(lldb::SBBreakpointLocation &breakpoint_location_sb) { + return SWIG_NewPointerObj(&breakpoint_location_sb, + SWIGTYPE_p_lldb__SBBreakpointLocation, 0); } -template <> -PyObject* -SBTypeToSWIGWrapper (lldb::SBValue* value_sb) -{ - return SWIG_NewPointerObj((void *) value_sb, SWIGTYPE_p_lldb__SBValue, 0); +PyObject *SBTypeToSWIGWrapper(lldb::SBValue &value_sb) { + return SWIG_NewPointerObj(&value_sb, SWIGTYPE_p_lldb__SBValue, 0); } -template <> -PyObject* -SBTypeToSWIGWrapper (lldb::SBCommandReturnObject* cmd_ret_obj_sb) -{ - return SWIG_NewPointerObj((void *) cmd_ret_obj_sb, SWIGTYPE_p_lldb__SBCommandReturnObject, 0); +PyObject *SBTypeToSWIGWrapper(lldb::SBCommandReturnObject &cmd_ret_obj_sb) { + return SWIG_NewPointerObj(&cmd_ret_obj_sb, + SWIGTYPE_p_lldb__SBCommandReturnObject, 0); } -template <> -PyObject* -SBTypeToSWIGWrapper (lldb::SBExecutionContext* ctx_sb) -{ - return SWIG_NewPointerObj((void *) ctx_sb, SWIGTYPE_p_lldb__SBExecutionContext, 0); +PyObject *SBTypeToSWIGWrapper(lldb::SBExecutionContext &ctx_sb) { + return SWIG_NewPointerObj(&ctx_sb, SWIGTYPE_p_lldb__SBExecutionContext, 0); } -template <> -PyObject* -SBTypeToSWIGWrapper (lldb::SBTypeSummaryOptions* summary_options_sb) -{ - return SWIG_NewPointerObj((void *) summary_options_sb, SWIGTYPE_p_lldb__SBTypeSummaryOptions, 0); +PyObject *SBTypeToSWIGWrapper(lldb::SBTypeSummaryOptions &summary_options_sb) { + return SWIG_NewPointerObj(&summary_options_sb, + SWIGTYPE_p_lldb__SBTypeSummaryOptions, 0); } -template <> -PyObject* -SBTypeToSWIGWrapper (lldb::SBStructuredData* structured_data_sb) -{ - return SWIG_NewPointerObj((void *) structured_data_sb, SWIGTYPE_p_lldb__SBStructuredData, 0); +PyObject *SBTypeToSWIGWrapper(lldb::SBStructuredData &structured_data_sb) { + return SWIG_NewPointerObj(&structured_data_sb, + SWIGTYPE_p_lldb__SBStructuredData, 0); } -template <> -PyObject* -SBTypeToSWIGWrapper (lldb::SBSymbolContext* sym_ctx_sb) -{ - return SWIG_NewPointerObj((void *) sym_ctx_sb, SWIGTYPE_p_lldb__SBSymbolContext, 0); +PyObject *SBTypeToSWIGWrapper(lldb::SBSymbolContext &sym_ctx_sb) { + return SWIG_NewPointerObj(&sym_ctx_sb, SWIGTYPE_p_lldb__SBSymbolContext, 0); } -template <> -PyObject* -SBTypeToSWIGWrapper (lldb::SBStream* stream_sb) -{ - return SWIG_NewPointerObj((void *) stream_sb, SWIGTYPE_p_lldb__SBStream, 0); +PyObject *SBTypeToSWIGWrapper(lldb::SBStream &stream_sb) { + return SWIG_NewPointerObj(&stream_sb, SWIGTYPE_p_lldb__SBStream, 0); } diff --git a/contrib/llvm-project/lldb/bindings/python/python-wrapper.swig b/contrib/llvm-project/lldb/bindings/python/python-wrapper.swig index 4c39e9c2c776..6dc8ca170390 100644 --- a/contrib/llvm-project/lldb/bindings/python/python-wrapper.swig +++ b/contrib/llvm-project/lldb/bindings/python/python-wrapper.swig @@ -1,9 +1,5 @@ %header %{ -template <typename T> -PyObject * -SBTypeToSWIGWrapper (T* item); - class PyErr_Cleaner { public: @@ -83,8 +79,9 @@ LLDBSwigPythonBreakpointCallbackFunction if (max_positional_args < 4) { return pfunc.Call(frame_arg, bp_loc_arg, dict); } else { + // FIXME: SBStructuredData leaked here lldb::SBStructuredData *args_value = new lldb::SBStructuredData(args_impl); - PythonObject args_arg(PyRefType::Owned, SBTypeToSWIGWrapper(args_value)); + PythonObject args_arg(PyRefType::Owned, SBTypeToSWIGWrapper(*args_value)); return pfunc.Call(frame_arg, bp_loc_arg, args_arg, dict); } } (); @@ -230,12 +227,11 @@ LLDBSwigPythonCreateSyntheticProvider if (!pfunc.IsAllocated()) Py_RETURN_NONE; - // I do not want the SBValue to be deallocated when going out of scope because python - // has ownership of it and will manage memory for this object by itself + // FIXME: SBValue leaked here lldb::SBValue *sb_value = new lldb::SBValue(valobj_sp); sb_value->SetPreferSyntheticValue(false); - PythonObject val_arg(PyRefType::Owned, SBTypeToSWIGWrapper(sb_value)); + PythonObject val_arg(PyRefType::Owned, SBTypeToSWIGWrapper(*sb_value)); if (!val_arg.IsAllocated()) Py_RETURN_NONE; @@ -288,7 +284,6 @@ LLDBSwigPythonCreateScriptedProcess if (python_class_name == NULL || python_class_name[0] == '\0' || !session_dictionary_name) Py_RETURN_NONE; - PyErr_Cleaner py_err_cleaner(true); auto dict = PythonModule::MainModule().ResolveName<PythonDictionary>(session_dictionary_name); @@ -300,10 +295,9 @@ LLDBSwigPythonCreateScriptedProcess return nullptr; } - // I do not want the SBTarget to be deallocated when going out of scope - // because python has ownership of it and will manage memory for this - // object by itself - PythonObject target_arg(PyRefType::Owned, SBTypeToSWIGWrapper(new lldb::SBTarget(target_sp))); + // FIXME: SBTarget leaked here + PythonObject target_arg( + PyRefType::Owned, SBTypeToSWIGWrapper(*new lldb::SBTarget(target_sp))); if (!target_arg.IsAllocated()) Py_RETURN_NONE; @@ -323,16 +317,71 @@ LLDBSwigPythonCreateScriptedProcess PythonObject result = {}; if (arg_info.get().max_positional_args == 2) { - if (args_impl != nullptr) { - error_string.assign("args passed, but __init__ does not take an args dictionary"); - Py_RETURN_NONE; - } - result = pfunc(target_arg, dict); - } else if (arg_info.get().max_positional_args >= 3) { - PythonObject args_arg(PyRefType::Owned, SBTypeToSWIGWrapper(new lldb::SBStructuredData(args_impl))); - result = pfunc(target_arg, args_arg, dict); + // FIXME: SBStructuredData leaked here + PythonObject args_arg(PyRefType::Owned, SBTypeToSWIGWrapper(*new lldb::SBStructuredData(args_impl))); + result = pfunc(target_arg, args_arg); } else { - error_string.assign("wrong number of arguments in __init__, should be 2 or 3 (not including self)"); + error_string.assign("wrong number of arguments in __init__, should be 2 (not including self)"); + Py_RETURN_NONE; + } + + if (result.IsAllocated()) + return result.release(); + Py_RETURN_NONE; +} + +SWIGEXPORT void* +LLDBSwigPythonCreateScriptedThread +( + const char *python_class_name, + const char *session_dictionary_name, + const lldb::ProcessSP& process_sp, + lldb_private::StructuredDataImpl *args_impl, + std::string &error_string +) +{ + if (python_class_name == NULL || python_class_name[0] == '\0' || !session_dictionary_name) + Py_RETURN_NONE; + + PyErr_Cleaner py_err_cleaner(true); + + auto dict = PythonModule::MainModule().ResolveName<PythonDictionary>(session_dictionary_name); + auto pfunc = PythonObject::ResolveNameWithDictionary<PythonCallable>(python_class_name, dict); + + if (!pfunc.IsAllocated()) { + error_string.append("could not find script class: "); + error_string.append(python_class_name); + return nullptr; + } + + // FIXME: This leaks the SBProcess object + PythonObject process_arg( + PyRefType::Owned, + SBTypeToSWIGWrapper(*new lldb::SBProcess(process_sp))); + + if (!process_arg.IsAllocated()) + Py_RETURN_NONE; + + llvm::Expected<PythonCallable::ArgInfo> arg_info = pfunc.GetArgInfo(); + if (!arg_info) { + llvm::handleAllErrors( + arg_info.takeError(), + [&](PythonException &E) { + error_string.append(E.ReadBacktrace()); + }, + [&](const llvm::ErrorInfoBase &E) { + error_string.append(E.message()); + }); + Py_RETURN_NONE; + } + + PythonObject result = {}; + if (arg_info.get().max_positional_args == 2) { + // FIXME: SBStructuredData leaked here + PythonObject args_arg(PyRefType::Owned, SBTypeToSWIGWrapper(*new lldb::SBStructuredData(args_impl))); + result = pfunc(process_arg, args_arg); + } else { + error_string.assign("wrong number of arguments in __init__, should be 2 (not including self)"); Py_RETURN_NONE; } @@ -366,10 +415,10 @@ LLDBSwigPythonCreateScriptedThreadPlan return nullptr; } - // I do not want the SBThreadPlan to be deallocated when going out of scope - // because python has ownership of it and will manage memory for this - // object by itself - PythonObject tp_arg(PyRefType::Owned, SBTypeToSWIGWrapper(new lldb::SBThreadPlan(thread_plan_sp))); + // FIXME: SBThreadPlan leaked here + PythonObject tp_arg( + PyRefType::Owned, + SBTypeToSWIGWrapper(*new lldb::SBThreadPlan(thread_plan_sp))); if (!tp_arg.IsAllocated()) Py_RETURN_NONE; @@ -395,7 +444,8 @@ LLDBSwigPythonCreateScriptedThreadPlan } result = pfunc(tp_arg, dict); } else if (arg_info.get().max_positional_args >= 3) { - PythonObject args_arg(PyRefType::Owned, SBTypeToSWIGWrapper(new lldb::SBStructuredData(args_impl))); + // FIXME: SBStructuredData leaked here + PythonObject args_arg(PyRefType::Owned, SBTypeToSWIGWrapper(*new lldb::SBStructuredData(args_impl))); result = pfunc(tp_arg, args_arg, dict); } else { error_string.assign("wrong number of arguments in __init__, should be 2 or 3 (not including self)"); @@ -477,12 +527,14 @@ LLDBSwigPythonCreateScriptedBreakpointResolver if (!pfunc.IsAllocated()) return nullptr; + // FIXME: SBBreakpoint leaked here lldb::SBBreakpoint *bkpt_value = new lldb::SBBreakpoint(breakpoint_sp); - PythonObject bkpt_arg(PyRefType::Owned, SBTypeToSWIGWrapper(bkpt_value)); + PythonObject bkpt_arg(PyRefType::Owned, SBTypeToSWIGWrapper(*bkpt_value)); + // FIXME: SBStructuredData leaked here lldb::SBStructuredData *args_value = new lldb::SBStructuredData(args_impl); - PythonObject args_arg(PyRefType::Owned, SBTypeToSWIGWrapper(args_value)); + PythonObject args_arg(PyRefType::Owned, SBTypeToSWIGWrapper(*args_value)); PythonObject result = pfunc(bkpt_arg, args_arg, dict); // FIXME: At this point we should check that the class we found supports all the methods @@ -585,13 +637,14 @@ LLDBSwigPythonCreateScriptedStopHook return nullptr; } + // FIXME: SBTarget leaked here lldb::SBTarget *target_val = new lldb::SBTarget(target_sp); + PythonObject target_arg(PyRefType::Owned, SBTypeToSWIGWrapper(*target_val)); - PythonObject target_arg(PyRefType::Owned, SBTypeToSWIGWrapper(target_val)); - + // FIXME: SBStructuredData leaked here lldb::SBStructuredData *args_value = new lldb::SBStructuredData(args_impl); - PythonObject args_arg(PyRefType::Owned, SBTypeToSWIGWrapper(args_value)); + PythonObject args_arg(PyRefType::Owned, SBTypeToSWIGWrapper(*args_value)); PythonObject result = pfunc(target_arg, args_arg, dict); @@ -918,6 +971,22 @@ LLDBSWIGPython_CastPyObjectToSBValue return sb_ptr; } +SWIGEXPORT void* +LLDBSWIGPython_CastPyObjectToSBMemoryRegionInfo +( + PyObject* data +) +{ + lldb::SBMemoryRegionInfo* sb_ptr = NULL; + + int valid_cast = SWIG_ConvertPtr(data, (void**)&sb_ptr, SWIGTYPE_p_lldb__SBMemoryRegionInfo, 0); + + if (valid_cast == -1) + return NULL; + + return sb_ptr; +} + SWIGEXPORT bool LLDBSwigPythonCallCommand ( @@ -940,8 +1009,6 @@ LLDBSwigPythonCallCommand if (!pfunc.IsAllocated()) return false; - // pass the pointer-to cmd_retobj_sb or watch the underlying object disappear from under you - // see comment above for SBCommandReturnObjectReleaser for further details auto argc = pfunc.GetArgInfo(); if (!argc) { llvm::consumeError(argc.takeError()); @@ -949,7 +1016,7 @@ LLDBSwigPythonCallCommand } PythonObject debugger_arg(PyRefType::Owned, SBTypeToSWIGWrapper(debugger_sb)); PythonObject exe_ctx_arg(PyRefType::Owned, SBTypeToSWIGWrapper(exe_ctx_sb)); - PythonObject cmd_retobj_arg(PyRefType::Owned, SBTypeToSWIGWrapper(&cmd_retobj_sb)); + PythonObject cmd_retobj_arg(PyRefType::Owned, SBTypeToSWIGWrapper(cmd_retobj_sb)); if (argc.get().max_positional_args < 5u) pfunc(debugger_arg, PythonString(args), cmd_retobj_arg, dict); @@ -981,11 +1048,9 @@ LLDBSwigPythonCallCommandObject if (!pfunc.IsAllocated()) return false; - // pass the pointer-to cmd_retobj_sb or watch the underlying object disappear from under you - // see comment above for SBCommandReturnObjectReleaser for further details PythonObject debugger_arg(PyRefType::Owned, SBTypeToSWIGWrapper(debugger_sb)); PythonObject exe_ctx_arg(PyRefType::Owned, SBTypeToSWIGWrapper(exe_ctx_sb)); - PythonObject cmd_retobj_arg(PyRefType::Owned, SBTypeToSWIGWrapper(&cmd_retobj_sb)); + PythonObject cmd_retobj_arg(PyRefType::Owned, SBTypeToSWIGWrapper(cmd_retobj_sb)); pfunc(debugger_arg, PythonString(args), exe_ctx_arg, cmd_retobj_arg); @@ -1011,10 +1076,9 @@ LLDBSWIGPythonCreateOSPlugin if (!pfunc.IsAllocated()) Py_RETURN_NONE; - // I do not want the SBProcess to be deallocated when going out of scope because python - // has ownership of it and will manage memory for this object by itself + // FIXME: This leaks the SBProcess object lldb::SBProcess *process_sb = new lldb::SBProcess(process_sp); - PythonObject process_arg(PyRefType::Owned, SBTypeToSWIGWrapper(process_sb)); + PythonObject process_arg(PyRefType::Owned, SBTypeToSWIGWrapper(*process_sb)); if (!process_arg.IsAllocated()) Py_RETURN_NONE; diff --git a/contrib/llvm-project/lldb/docs/design/reproducers.rst b/contrib/llvm-project/lldb/docs/design/reproducers.rst index 99e34d812dee..cac8721196d3 100644 --- a/contrib/llvm-project/lldb/docs/design/reproducers.rst +++ b/contrib/llvm-project/lldb/docs/design/reproducers.rst @@ -33,7 +33,7 @@ late to capture initialization of the debugger. .. code-block:: bash - > lldb --capture + $ lldb --capture In capture mode, LLDB will keep track of all the information it needs to replay the current debug session. Most data is captured lazily to limit the impact on @@ -70,7 +70,7 @@ were passed to LLDB during capture are already part of the reproducer. .. code-block:: bash - > lldb --replay /path/to/reproducer + $ lldb --replay /path/to/reproducer During replay LLDB will behave similar to batch mode. The session should be diff --git a/contrib/llvm-project/lldb/docs/design/sbapi.rst b/contrib/llvm-project/lldb/docs/design/sbapi.rst index 676509bbd99e..f4a7ca271be6 100644 --- a/contrib/llvm-project/lldb/docs/design/sbapi.rst +++ b/contrib/llvm-project/lldb/docs/design/sbapi.rst @@ -68,7 +68,7 @@ Like other clang-based tools it requires a compilation database :: - ./bin/lldb-instr /path/to/lldb/source/API/SBDebugger.cpp + $ ./bin/lldb-instr /path/to/lldb/source/API/SBDebugger.cpp The tool will automatically insert ``LLDB_RECORD`` macros inline, however you diff --git a/contrib/llvm-project/lldb/docs/man/lldb.rst b/contrib/llvm-project/lldb/docs/man/lldb.rst index b75288db380d..10b143cd0de8 100644 --- a/contrib/llvm-project/lldb/docs/man/lldb.rst +++ b/contrib/llvm-project/lldb/docs/man/lldb.rst @@ -111,7 +111,7 @@ COMMANDS .. option:: --source-quietly - Tells the debugger to execute this one-line lldb command before any file has been loaded. + Tells the debugger not to echo commands while sourcing files or one-line commands provided on the command line. .. option:: --source <file> @@ -234,6 +234,10 @@ SCRIPTING Alias for --script-language +.. option:: --print-script-interpreter-info + + Prints out a json dictionary with information about the scripting language interpreter. + .. option:: --python-path Prints out the path to the lldb.py file for this version of lldb. diff --git a/contrib/llvm-project/lldb/include/lldb/API/SBDebugger.h b/contrib/llvm-project/lldb/include/lldb/API/SBDebugger.h index ef62141f579d..64081f79205d 100644 --- a/contrib/llvm-project/lldb/include/lldb/API/SBDebugger.h +++ b/contrib/llvm-project/lldb/include/lldb/API/SBDebugger.h @@ -247,6 +247,8 @@ public: lldb::ScriptLanguage GetScriptingLanguage(const char *script_language_name); + SBStructuredData GetScriptInterpreterInfo(ScriptLanguage); + static const char *GetVersionString(); static const char *StateAsCString(lldb::StateType state); diff --git a/contrib/llvm-project/lldb/include/lldb/API/SBExecutionContext.h b/contrib/llvm-project/lldb/include/lldb/API/SBExecutionContext.h index 06ece6fbc0fa..70fc83e84e4e 100644 --- a/contrib/llvm-project/lldb/include/lldb/API/SBExecutionContext.h +++ b/contrib/llvm-project/lldb/include/lldb/API/SBExecutionContext.h @@ -50,8 +50,6 @@ public: SBFrame GetFrame() const; protected: - void reset(lldb::ExecutionContextRefSP &event_sp); - lldb_private::ExecutionContextRef *get() const; private: diff --git a/contrib/llvm-project/lldb/include/lldb/API/SBMemoryRegionInfo.h b/contrib/llvm-project/lldb/include/lldb/API/SBMemoryRegionInfo.h index 122226b9a0c5..be55de4ead1f 100644 --- a/contrib/llvm-project/lldb/include/lldb/API/SBMemoryRegionInfo.h +++ b/contrib/llvm-project/lldb/include/lldb/API/SBMemoryRegionInfo.h @@ -20,6 +20,10 @@ public: SBMemoryRegionInfo(const lldb::SBMemoryRegionInfo &rhs); + SBMemoryRegionInfo(const char *name, lldb::addr_t begin, lldb::addr_t end, + uint32_t permissions, bool mapped, + bool stack_memory = false); + ~SBMemoryRegionInfo(); const lldb::SBMemoryRegionInfo & @@ -117,6 +121,8 @@ private: friend class SBProcess; friend class SBMemoryRegionInfoList; + friend class lldb_private::ScriptInterpreter; + lldb_private::MemoryRegionInfo &ref(); const lldb_private::MemoryRegionInfo &ref() const; diff --git a/contrib/llvm-project/lldb/include/lldb/API/SBMemoryRegionInfoList.h b/contrib/llvm-project/lldb/include/lldb/API/SBMemoryRegionInfoList.h index a7122ee9108a..1d939dff55fa 100644 --- a/contrib/llvm-project/lldb/include/lldb/API/SBMemoryRegionInfoList.h +++ b/contrib/llvm-project/lldb/include/lldb/API/SBMemoryRegionInfoList.h @@ -27,6 +27,9 @@ public: uint32_t GetSize() const; + bool GetMemoryRegionContainingAddress(lldb::addr_t addr, + SBMemoryRegionInfo ®ion_info); + bool GetMemoryRegionAtIndex(uint32_t idx, SBMemoryRegionInfo ®ion_info); void Append(lldb::SBMemoryRegionInfo ®ion); diff --git a/contrib/llvm-project/lldb/include/lldb/Breakpoint/Breakpoint.h b/contrib/llvm-project/lldb/include/lldb/Breakpoint/Breakpoint.h index f2e2a0d22784..40435d5c3d0f 100644 --- a/contrib/llvm-project/lldb/include/lldb/Breakpoint/Breakpoint.h +++ b/contrib/llvm-project/lldb/include/lldb/Breakpoint/Breakpoint.h @@ -22,6 +22,7 @@ #include "lldb/Breakpoint/Stoppoint.h" #include "lldb/Breakpoint/StoppointHitCounter.h" #include "lldb/Core/SearchFilter.h" +#include "lldb/Target/Statistics.h" #include "lldb/Utility/Event.h" #include "lldb/Utility/StringList.h" #include "lldb/Utility/StructuredData.h" @@ -576,6 +577,12 @@ public: static lldb::BreakpointSP CopyFromBreakpoint(lldb::TargetSP new_target, const Breakpoint &bp_to_copy_from); + /// Get statistics associated with this breakpoint in JSON format. + llvm::json::Value GetStatistics(); + + /// Get the time it took to resolve all locations in this breakpoint. + StatsDuration GetResolveTime() const { return m_resolve_time; } + protected: friend class Target; // Protected Methods @@ -653,6 +660,8 @@ private: BreakpointName::Permissions m_permissions; + StatsDuration m_resolve_time{0.0}; + void SendBreakpointChangedEvent(lldb::BreakpointEventType eventKind); void SendBreakpointChangedEvent(BreakpointEventData *data); diff --git a/contrib/llvm-project/lldb/include/lldb/Core/Address.h b/contrib/llvm-project/lldb/include/lldb/Core/Address.h index ec393a1871e3..dc50e27ca277 100644 --- a/contrib/llvm-project/lldb/include/lldb/Core/Address.h +++ b/contrib/llvm-project/lldb/include/lldb/Core/Address.h @@ -210,6 +210,10 @@ public: } }; + /// Write a description of this object to a Stream. + bool GetDescription(Stream &s, Target &target, + lldb::DescriptionLevel level) const; + /// Dump a description of this object to a Stream. /// /// Dump a description of the contents of this object to the supplied stream diff --git a/contrib/llvm-project/lldb/include/lldb/Core/AddressRange.h b/contrib/llvm-project/lldb/include/lldb/Core/AddressRange.h index 6fbdc35c9168..4a33c2d79587 100644 --- a/contrib/llvm-project/lldb/include/lldb/Core/AddressRange.h +++ b/contrib/llvm-project/lldb/include/lldb/Core/AddressRange.h @@ -242,8 +242,6 @@ protected: lldb::addr_t m_byte_size = 0; ///< The size in bytes of this address range. }; -// bool operator== (const AddressRange& lhs, const AddressRange& rhs); - } // namespace lldb_private #endif // LLDB_CORE_ADDRESSRANGE_H diff --git a/contrib/llvm-project/lldb/include/lldb/Core/Communication.h b/contrib/llvm-project/lldb/include/lldb/Core/Communication.h index 930e927f6783..fdcb6c5fb982 100644 --- a/contrib/llvm-project/lldb/include/lldb/Core/Communication.h +++ b/contrib/llvm-project/lldb/include/lldb/Core/Communication.h @@ -209,6 +209,22 @@ public: size_t Write(const void *src, size_t src_len, lldb::ConnectionStatus &status, Status *error_ptr); + /// Repeatedly attempt writing until either \a src_len bytes are written + /// or a permanent failure occurs. + /// + /// \param[in] src + /// A source buffer that must be at least \a src_len bytes + /// long. + /// + /// \param[in] src_len + /// The number of bytes to attempt to write, and also the + /// number of bytes are currently available in \a src. + /// + /// \return + /// The number of bytes actually Written. + size_t WriteAll(const void *src, size_t src_len, + lldb::ConnectionStatus &status, Status *error_ptr); + /// Sets the connection that it to be used by this class. /// /// By making a communication class that uses different connections it diff --git a/contrib/llvm-project/lldb/include/lldb/Core/Disassembler.h b/contrib/llvm-project/lldb/include/lldb/Core/Disassembler.h index 622c23ff6492..0925bf358b9c 100644 --- a/contrib/llvm-project/lldb/include/lldb/Core/Disassembler.h +++ b/contrib/llvm-project/lldb/include/lldb/Core/Disassembler.h @@ -150,6 +150,10 @@ public: virtual bool HasDelaySlot(); + virtual bool IsLoad() = 0; + + virtual bool IsAuthenticated() = 0; + bool CanSetBreakpoint (); virtual size_t Decode(const Disassembler &disassembler, @@ -336,6 +340,10 @@ public: bool HasDelaySlot() override; + bool IsLoad() override; + + bool IsAuthenticated() override; + void CalculateMnemonicOperandsAndComment( const ExecutionContext *exe_ctx) override { // TODO: fill this in and put opcode name into Instruction::m_opcode_name, diff --git a/contrib/llvm-project/lldb/include/lldb/Core/IOHandler.h b/contrib/llvm-project/lldb/include/lldb/Core/IOHandler.h index 4a3b788e3ea1..7011dd1e8e04 100644 --- a/contrib/llvm-project/lldb/include/lldb/Core/IOHandler.h +++ b/contrib/llvm-project/lldb/include/lldb/Core/IOHandler.h @@ -442,8 +442,6 @@ protected: bool m_multi_line; bool m_color_prompts; bool m_interrupt_exits; - bool m_editing; // Set to true when fetching a line manually (not using - // libedit) std::string m_line_buffer; }; diff --git a/contrib/llvm-project/lldb/include/lldb/Core/Mangled.h b/contrib/llvm-project/lldb/include/lldb/Core/Mangled.h index d11d13b63cfc..c0542157f85d 100644 --- a/contrib/llvm-project/lldb/include/lldb/Core/Mangled.h +++ b/contrib/llvm-project/lldb/include/lldb/Core/Mangled.h @@ -44,7 +44,8 @@ public: eManglingSchemeNone = 0, eManglingSchemeMSVC, eManglingSchemeItanium, - eManglingSchemeRustV0 + eManglingSchemeRustV0, + eManglingSchemeD }; /// Default constructor. diff --git a/contrib/llvm-project/lldb/include/lldb/Core/Module.h b/contrib/llvm-project/lldb/include/lldb/Core/Module.h index dd7100c4616c..b80f4fd9b85a 100644 --- a/contrib/llvm-project/lldb/include/lldb/Core/Module.h +++ b/contrib/llvm-project/lldb/include/lldb/Core/Module.h @@ -16,6 +16,7 @@ #include "lldb/Symbol/SymbolContextScope.h" #include "lldb/Symbol/TypeSystem.h" #include "lldb/Target/PathMappingList.h" +#include "lldb/Target/Statistics.h" #include "lldb/Utility/ArchSpec.h" #include "lldb/Utility/ConstString.h" #include "lldb/Utility/FileSpec.h" @@ -57,6 +58,15 @@ class TypeList; class TypeMap; class VariableList; +/// Options used by Module::FindFunctions. This cannot be a nested class +/// because it must be forward-declared in ModuleList.h. +struct ModuleFunctionSearchOptions { + /// Include the symbol table. + bool include_symbols = false; + /// Include inlined functions. + bool include_inlines = false; +}; + /// \class Module Module.h "lldb/Core/Module.h" /// A class that describes an executable image and its associated /// object and symbol files. @@ -304,8 +314,9 @@ public: /// matches. void FindFunctions(ConstString name, const CompilerDeclContext &parent_decl_ctx, - lldb::FunctionNameType name_type_mask, bool symbols_ok, - bool inlines_ok, SymbolContextList &sc_list); + lldb::FunctionNameType name_type_mask, + const ModuleFunctionSearchOptions &options, + SymbolContextList &sc_list); /// Find functions by name. /// @@ -319,8 +330,9 @@ public: /// \param[out] sc_list /// A symbol context list that gets filled in with all of the /// matches. - void FindFunctions(const RegularExpression ®ex, bool symbols_ok, - bool inlines_ok, SymbolContextList &sc_list); + void FindFunctions(const RegularExpression ®ex, + const ModuleFunctionSearchOptions &options, + SymbolContextList &sc_list); /// Find addresses by file/line /// @@ -859,6 +871,18 @@ public: /// Update the ArchSpec to a more specific variant. bool MergeArchitecture(const ArchSpec &arch_spec); + /// Accessor for the symbol table parse time metric. + /// + /// The value is returned as a reference to allow it to be updated by the + /// ElapsedTime RAII object. + StatsDuration &GetSymtabParseTime() { return m_symtab_parse_time; } + + /// Accessor for the symbol table index time metric. + /// + /// The value is returned as a reference to allow it to be updated by the + /// ElapsedTime RAII object. + StatsDuration &GetSymtabIndexTime() { return m_symtab_index_time; } + /// \class LookupInfo Module.h "lldb/Core/Module.h" /// A class that encapsulates name lookup information. /// @@ -984,6 +1008,14 @@ protected: mutable bool m_file_has_changed : 1, m_first_file_changed_log : 1; /// See if the module was modified after it /// was initially opened. + /// We store a symbol table parse time duration here because we might have + /// an object file and a symbol file which both have symbol tables. The parse + /// time for the symbol tables can be aggregated here. + StatsDuration m_symtab_parse_time{0.0}; + /// We store a symbol named index time duration here because we might have + /// an object file and a symbol file which both have symbol tables. The parse + /// time for the symbol tables can be aggregated here. + StatsDuration m_symtab_index_time{0.0}; /// Resolve a file or load virtual address. /// diff --git a/contrib/llvm-project/lldb/include/lldb/Core/ModuleList.h b/contrib/llvm-project/lldb/include/lldb/Core/ModuleList.h index 07dddd18357b..6ca5813d9662 100644 --- a/contrib/llvm-project/lldb/include/lldb/Core/ModuleList.h +++ b/contrib/llvm-project/lldb/include/lldb/Core/ModuleList.h @@ -45,6 +45,7 @@ class Target; class TypeList; class UUID; class VariableList; +struct ModuleFunctionSearchOptions; class ModuleListProperties : public Properties { mutable llvm::sys::RWMutex m_symlink_paths_mutex; @@ -158,7 +159,7 @@ public: /// ModulesDidLoad may be deferred when adding multiple Modules /// to the Target, but it must be called at the end, /// before resuming execution. - bool AppendIfNeeded(const lldb::ModuleSP &module_sp, bool notify = true); + bool AppendIfNeeded(const lldb::ModuleSP &new_module, bool notify = true); void Append(const ModuleList &module_list); @@ -252,7 +253,7 @@ public: /// \see Module::FindFunctions () void FindFunctions(ConstString name, lldb::FunctionNameType name_type_mask, - bool include_symbols, bool include_inlines, + const ModuleFunctionSearchOptions &options, SymbolContextList &sc_list) const; /// \see Module::FindFunctionSymbols () @@ -261,8 +262,9 @@ public: SymbolContextList &sc_list); /// \see Module::FindFunctions () - void FindFunctions(const RegularExpression &name, bool include_symbols, - bool include_inlines, SymbolContextList &sc_list); + void FindFunctions(const RegularExpression &name, + const ModuleFunctionSearchOptions &options, + SymbolContextList &sc_list); /// Find global and static variables by name. /// diff --git a/contrib/llvm-project/lldb/include/lldb/Core/PluginInterface.h b/contrib/llvm-project/lldb/include/lldb/Core/PluginInterface.h index 5bdb2f45b665..e9fd2b263a9e 100644 --- a/contrib/llvm-project/lldb/include/lldb/Core/PluginInterface.h +++ b/contrib/llvm-project/lldb/include/lldb/Core/PluginInterface.h @@ -9,7 +9,7 @@ #ifndef LLDB_CORE_PLUGININTERFACE_H #define LLDB_CORE_PLUGININTERFACE_H -#include "lldb/lldb-private.h" +#include "llvm/ADT/StringRef.h" namespace lldb_private { @@ -18,9 +18,7 @@ public: PluginInterface() = default; virtual ~PluginInterface() = default; - virtual ConstString GetPluginName() = 0; - - virtual uint32_t GetPluginVersion() = 0; + virtual llvm::StringRef GetPluginName() = 0; PluginInterface(const PluginInterface &) = delete; PluginInterface &operator=(const PluginInterface &) = delete; diff --git a/contrib/llvm-project/lldb/include/lldb/Core/PluginManager.h b/contrib/llvm-project/lldb/include/lldb/Core/PluginManager.h index be91929c62e1..7dc99bf3e755 100644 --- a/contrib/llvm-project/lldb/include/lldb/Core/PluginManager.h +++ b/contrib/llvm-project/lldb/include/lldb/Core/PluginManager.h @@ -54,7 +54,7 @@ public: static void Terminate(); // ABI - static bool RegisterPlugin(ConstString name, const char *description, + static bool RegisterPlugin(llvm::StringRef name, llvm::StringRef description, ABICreateInstance create_callback); static bool UnregisterPlugin(ABICreateInstance create_callback); @@ -62,7 +62,7 @@ public: static ABICreateInstance GetABICreateCallbackAtIndex(uint32_t idx); // Architecture - static void RegisterPlugin(ConstString name, llvm::StringRef description, + static void RegisterPlugin(llvm::StringRef name, llvm::StringRef description, ArchitectureCreateInstance create_callback); static void UnregisterPlugin(ArchitectureCreateInstance create_callback); @@ -71,7 +71,7 @@ public: CreateArchitectureInstance(const ArchSpec &arch); // Disassembler - static bool RegisterPlugin(ConstString name, const char *description, + static bool RegisterPlugin(llvm::StringRef name, llvm::StringRef description, DisassemblerCreateInstance create_callback); static bool UnregisterPlugin(DisassemblerCreateInstance create_callback); @@ -80,11 +80,11 @@ public: GetDisassemblerCreateCallbackAtIndex(uint32_t idx); static DisassemblerCreateInstance - GetDisassemblerCreateCallbackForPluginName(ConstString name); + GetDisassemblerCreateCallbackForPluginName(llvm::StringRef name); // DynamicLoader static bool - RegisterPlugin(ConstString name, const char *description, + RegisterPlugin(llvm::StringRef name, llvm::StringRef description, DynamicLoaderCreateInstance create_callback, DebuggerInitializeCallback debugger_init_callback = nullptr); @@ -94,11 +94,11 @@ public: GetDynamicLoaderCreateCallbackAtIndex(uint32_t idx); static DynamicLoaderCreateInstance - GetDynamicLoaderCreateCallbackForPluginName(ConstString name); + GetDynamicLoaderCreateCallbackForPluginName(llvm::StringRef name); // JITLoader static bool - RegisterPlugin(ConstString name, const char *description, + RegisterPlugin(llvm::StringRef name, llvm::StringRef description, JITLoaderCreateInstance create_callback, DebuggerInitializeCallback debugger_init_callback = nullptr); @@ -108,7 +108,7 @@ public: GetJITLoaderCreateCallbackAtIndex(uint32_t idx); // EmulateInstruction - static bool RegisterPlugin(ConstString name, const char *description, + static bool RegisterPlugin(llvm::StringRef name, llvm::StringRef description, EmulateInstructionCreateInstance create_callback); static bool @@ -118,10 +118,10 @@ public: GetEmulateInstructionCreateCallbackAtIndex(uint32_t idx); static EmulateInstructionCreateInstance - GetEmulateInstructionCreateCallbackForPluginName(ConstString name); + GetEmulateInstructionCreateCallbackForPluginName(llvm::StringRef name); // OperatingSystem - static bool RegisterPlugin(ConstString name, const char *description, + static bool RegisterPlugin(llvm::StringRef name, llvm::StringRef description, OperatingSystemCreateInstance create_callback, DebuggerInitializeCallback debugger_init_callback); @@ -131,10 +131,10 @@ public: GetOperatingSystemCreateCallbackAtIndex(uint32_t idx); static OperatingSystemCreateInstance - GetOperatingSystemCreateCallbackForPluginName(ConstString name); + GetOperatingSystemCreateCallbackForPluginName(llvm::StringRef name); // Language - static bool RegisterPlugin(ConstString name, const char *description, + static bool RegisterPlugin(llvm::StringRef name, llvm::StringRef description, LanguageCreateInstance create_callback); static bool UnregisterPlugin(LanguageCreateInstance create_callback); @@ -143,7 +143,7 @@ public: // LanguageRuntime static bool RegisterPlugin( - ConstString name, const char *description, + llvm::StringRef name, llvm::StringRef description, LanguageRuntimeCreateInstance create_callback, LanguageRuntimeGetCommandObject command_callback = nullptr, LanguageRuntimeGetExceptionPrecondition precondition_callback = nullptr); @@ -160,7 +160,7 @@ public: GetLanguageRuntimeGetExceptionPreconditionAtIndex(uint32_t idx); // SystemRuntime - static bool RegisterPlugin(ConstString name, const char *description, + static bool RegisterPlugin(llvm::StringRef name, llvm::StringRef description, SystemRuntimeCreateInstance create_callback); static bool UnregisterPlugin(SystemRuntimeCreateInstance create_callback); @@ -170,7 +170,7 @@ public: // ObjectFile static bool - RegisterPlugin(ConstString name, const char *description, + RegisterPlugin(llvm::StringRef name, llvm::StringRef description, ObjectFileCreateInstance create_callback, ObjectFileCreateMemoryInstance create_memory_callback, ObjectFileGetModuleSpecifications get_module_specifications, @@ -188,15 +188,16 @@ public: GetObjectFileGetModuleSpecificationsCallbackAtIndex(uint32_t idx); static ObjectFileCreateMemoryInstance - GetObjectFileCreateMemoryCallbackForPluginName(ConstString name); + GetObjectFileCreateMemoryCallbackForPluginName(llvm::StringRef name); static Status SaveCore(const lldb::ProcessSP &process_sp, const FileSpec &outfile, - lldb::SaveCoreStyle &core_style); + lldb::SaveCoreStyle &core_style, + llvm::StringRef plugin_name); // ObjectContainer static bool - RegisterPlugin(ConstString name, const char *description, + RegisterPlugin(llvm::StringRef name, llvm::StringRef description, ObjectContainerCreateInstance create_callback, ObjectFileGetModuleSpecifications get_module_specifications); @@ -210,7 +211,7 @@ public: // Platform static bool - RegisterPlugin(ConstString name, const char *description, + RegisterPlugin(llvm::StringRef name, llvm::StringRef description, PlatformCreateInstance create_callback, DebuggerInitializeCallback debugger_init_callback = nullptr); @@ -219,17 +220,17 @@ public: static PlatformCreateInstance GetPlatformCreateCallbackAtIndex(uint32_t idx); static PlatformCreateInstance - GetPlatformCreateCallbackForPluginName(ConstString name); + GetPlatformCreateCallbackForPluginName(llvm::StringRef name); - static const char *GetPlatformPluginNameAtIndex(uint32_t idx); + static llvm::StringRef GetPlatformPluginNameAtIndex(uint32_t idx); - static const char *GetPlatformPluginDescriptionAtIndex(uint32_t idx); + static llvm::StringRef GetPlatformPluginDescriptionAtIndex(uint32_t idx); static void AutoCompletePlatformName(llvm::StringRef partial_name, CompletionRequest &request); // Process static bool - RegisterPlugin(ConstString name, const char *description, + RegisterPlugin(llvm::StringRef name, llvm::StringRef description, ProcessCreateInstance create_callback, DebuggerInitializeCallback debugger_init_callback = nullptr); @@ -238,17 +239,17 @@ public: static ProcessCreateInstance GetProcessCreateCallbackAtIndex(uint32_t idx); static ProcessCreateInstance - GetProcessCreateCallbackForPluginName(ConstString name); + GetProcessCreateCallbackForPluginName(llvm::StringRef name); - static const char *GetProcessPluginNameAtIndex(uint32_t idx); + static llvm::StringRef GetProcessPluginNameAtIndex(uint32_t idx); - static const char *GetProcessPluginDescriptionAtIndex(uint32_t idx); + static llvm::StringRef GetProcessPluginDescriptionAtIndex(uint32_t idx); static void AutoCompleteProcessName(llvm::StringRef partial_name, CompletionRequest &request); // ScriptInterpreter - static bool RegisterPlugin(ConstString name, const char *description, + static bool RegisterPlugin(llvm::StringRef name, llvm::StringRef description, lldb::ScriptLanguage script_lang, ScriptInterpreterCreateInstance create_callback); @@ -296,7 +297,7 @@ public: /// \return /// Returns true upon success; otherwise, false. static bool - RegisterPlugin(ConstString name, const char *description, + RegisterPlugin(llvm::StringRef name, llvm::StringRef description, StructuredDataPluginCreateInstance create_callback, DebuggerInitializeCallback debugger_init_callback = nullptr, StructuredDataFilterLaunchInfo filter_callback = nullptr); @@ -313,7 +314,7 @@ public: // SymbolFile static bool - RegisterPlugin(ConstString name, const char *description, + RegisterPlugin(llvm::StringRef name, llvm::StringRef description, SymbolFileCreateInstance create_callback, DebuggerInitializeCallback debugger_init_callback = nullptr); @@ -323,7 +324,7 @@ public: GetSymbolFileCreateCallbackAtIndex(uint32_t idx); // SymbolVendor - static bool RegisterPlugin(ConstString name, const char *description, + static bool RegisterPlugin(llvm::StringRef name, llvm::StringRef description, SymbolVendorCreateInstance create_callback); static bool UnregisterPlugin(SymbolVendorCreateInstance create_callback); @@ -333,7 +334,7 @@ public: // Trace static bool RegisterPlugin( - ConstString name, const char *description, + llvm::StringRef name, llvm::StringRef description, TraceCreateInstanceForSessionFile create_callback_for_session_file, TraceCreateInstanceForLiveProcess create_callback_for_live_process, llvm::StringRef schema); @@ -342,10 +343,10 @@ public: UnregisterPlugin(TraceCreateInstanceForSessionFile create_callback); static TraceCreateInstanceForSessionFile - GetTraceCreateCallback(ConstString plugin_name); + GetTraceCreateCallback(llvm::StringRef plugin_name); static TraceCreateInstanceForLiveProcess - GetTraceCreateCallbackForLiveProcess(ConstString plugin_name); + GetTraceCreateCallbackForLiveProcess(llvm::StringRef plugin_name); /// Get the JSON schema for a trace session file corresponding to the given /// plugin. @@ -356,7 +357,7 @@ public: /// \return /// An empty \a StringRef if no plugin was found with that plugin name, /// otherwise the actual schema is returned. - static llvm::StringRef GetTraceSchema(ConstString plugin_name); + static llvm::StringRef GetTraceSchema(llvm::StringRef plugin_name); /// Get the JSON schema for a trace session file corresponding to the plugin /// given by its index. @@ -375,16 +376,16 @@ public: /// This callback is used to create a CommandObject that will be listed /// under "thread trace export". Can be \b null. static bool RegisterPlugin( - ConstString name, const char *description, + llvm::StringRef name, llvm::StringRef description, TraceExporterCreateInstance create_callback, ThreadTraceExportCommandCreator create_thread_trace_export_command); static TraceExporterCreateInstance - GetTraceExporterCreateCallback(ConstString plugin_name); + GetTraceExporterCreateCallback(llvm::StringRef plugin_name); static bool UnregisterPlugin(TraceExporterCreateInstance create_callback); - static const char *GetTraceExporterPluginNameAtIndex(uint32_t index); + static llvm::StringRef GetTraceExporterPluginNameAtIndex(uint32_t index); /// Return the callback used to create the CommandObject that will be listed /// under "thread trace export". Can be \b null. @@ -392,7 +393,7 @@ public: GetThreadTraceExportCommandCreatorAtIndex(uint32_t index); // UnwindAssembly - static bool RegisterPlugin(ConstString name, const char *description, + static bool RegisterPlugin(llvm::StringRef name, llvm::StringRef description, UnwindAssemblyCreateInstance create_callback); static bool UnregisterPlugin(UnwindAssemblyCreateInstance create_callback); @@ -401,7 +402,7 @@ public: GetUnwindAssemblyCreateCallbackAtIndex(uint32_t idx); // MemoryHistory - static bool RegisterPlugin(ConstString name, const char *description, + static bool RegisterPlugin(llvm::StringRef name, llvm::StringRef description, MemoryHistoryCreateInstance create_callback); static bool UnregisterPlugin(MemoryHistoryCreateInstance create_callback); @@ -411,7 +412,7 @@ public: // InstrumentationRuntime static bool - RegisterPlugin(ConstString name, const char *description, + RegisterPlugin(llvm::StringRef name, llvm::StringRef description, InstrumentationRuntimeCreateInstance create_callback, InstrumentationRuntimeGetType get_type_callback); @@ -425,7 +426,7 @@ public: GetInstrumentationRuntimeCreateCallbackAtIndex(uint32_t idx); // TypeSystem - static bool RegisterPlugin(ConstString name, const char *description, + static bool RegisterPlugin(llvm::StringRef name, llvm::StringRef description, TypeSystemCreateInstance create_callback, LanguageSet supported_languages_for_types, LanguageSet supported_languages_for_expressions); @@ -440,7 +441,7 @@ public: static LanguageSet GetAllTypeSystemSupportedLanguagesForExpressions(); // REPL - static bool RegisterPlugin(ConstString name, const char *description, + static bool RegisterPlugin(llvm::StringRef name, llvm::StringRef description, REPLCreateInstance create_callback, LanguageSet supported_languages); diff --git a/contrib/llvm-project/lldb/include/lldb/Core/RichManglingContext.h b/contrib/llvm-project/lldb/include/lldb/Core/RichManglingContext.h index 48102ec0b1cf..a6b7af8d8d7e 100644 --- a/contrib/llvm-project/lldb/include/lldb/Core/RichManglingContext.h +++ b/contrib/llvm-project/lldb/include/lldb/Core/RichManglingContext.h @@ -42,9 +42,6 @@ public: /// If this symbol describes a constructor or destructor. bool IsCtorOrDtor() const; - /// If this symbol describes a function. - bool IsFunction() const; - /// Get the base name of a function. This doesn't include trailing template /// arguments, ie "a::b<int>" gives "b". The result will overwrite the /// internal buffer. It can be obtained via GetBufferRef(). diff --git a/contrib/llvm-project/lldb/include/lldb/Core/Section.h b/contrib/llvm-project/lldb/include/lldb/Core/Section.h index 3d4ab154e743..8a9fea374314 100644 --- a/contrib/llvm-project/lldb/include/lldb/Core/Section.h +++ b/contrib/llvm-project/lldb/include/lldb/Core/Section.h @@ -89,6 +89,12 @@ public: void Clear() { m_sections.clear(); } + /// Get the debug information size from all sections that contain debug + /// information. Symbol tables are not considered part of the debug + /// information for this call, just known sections that contain debug + /// information. + uint64_t GetDebugInfoSize() const; + protected: collection m_sections; }; @@ -236,6 +242,13 @@ public: void SetIsRelocated(bool b) { m_relocated = b; } + /// Returns true if this section contains debug information. Symbol tables + /// are not considered debug information since some symbols might contain + /// debug information (STABS, COFF) but not all symbols do, so to keep this + /// fast and simple only sections that contains only debug information should + /// return true. + bool ContainsOnlyDebugInfo() const; + protected: ObjectFile *m_obj_file; // The object file that data for this section should // be read from diff --git a/contrib/llvm-project/lldb/include/lldb/Core/StructuredDataImpl.h b/contrib/llvm-project/lldb/include/lldb/Core/StructuredDataImpl.h index 929ce21fb2f9..d6f64451e5c2 100644 --- a/contrib/llvm-project/lldb/include/lldb/Core/StructuredDataImpl.h +++ b/contrib/llvm-project/lldb/include/lldb/Core/StructuredDataImpl.h @@ -152,6 +152,8 @@ public: return (::snprintf(dst, dst_len, "%s", result.data())); } + StructuredData::ObjectSP GetObjectSP() const { return m_data_sp; } + private: lldb::StructuredDataPluginWP m_plugin_wp; StructuredData::ObjectSP m_data_sp; diff --git a/contrib/llvm-project/lldb/include/lldb/Core/ValueObjectConstResultImpl.h b/contrib/llvm-project/lldb/include/lldb/Core/ValueObjectConstResultImpl.h index 2536c51fa574..5a7a079d3095 100644 --- a/contrib/llvm-project/lldb/include/lldb/Core/ValueObjectConstResultImpl.h +++ b/contrib/llvm-project/lldb/include/lldb/Core/ValueObjectConstResultImpl.h @@ -68,7 +68,6 @@ private: ValueObject *m_impl_backend; lldb::addr_t m_live_address; AddressType m_live_address_type; - lldb::ValueObjectSP m_load_addr_backend; lldb::ValueObjectSP m_address_of_backend; ValueObjectConstResultImpl(const ValueObjectConstResultImpl &) = delete; diff --git a/contrib/llvm-project/lldb/include/lldb/Core/ValueObjectDynamicValue.h b/contrib/llvm-project/lldb/include/lldb/Core/ValueObjectDynamicValue.h index 8822a1d39249..09dcd0f968be 100644 --- a/contrib/llvm-project/lldb/include/lldb/Core/ValueObjectDynamicValue.h +++ b/contrib/llvm-project/lldb/include/lldb/Core/ValueObjectDynamicValue.h @@ -32,7 +32,7 @@ class Status; /// set lldb type. class ValueObjectDynamicValue : public ValueObject { public: - ~ValueObjectDynamicValue() override; + ~ValueObjectDynamicValue() = default; llvm::Optional<uint64_t> GetByteSize() override; @@ -68,14 +68,6 @@ public: lldb::ValueObjectSP GetStaticValue() override { return m_parent->GetSP(); } - void SetOwningSP(lldb::ValueObjectSP &owning_sp) { - if (m_owning_valobj_sp == owning_sp) - return; - - assert(m_owning_valobj_sp.get() == nullptr); - m_owning_valobj_sp = owning_sp; - } - bool SetValueFromCString(const char *value_str, Status &error) override; bool SetData(DataExtractor &data, Status &error) override; @@ -117,7 +109,6 @@ protected: Address m_address; ///< The variable that this value object is based upon TypeAndOrName m_dynamic_type_info; // We can have a type_sp or just a name - lldb::ValueObjectSP m_owning_valobj_sp; lldb::DynamicValueType m_use_dynamic; TypeImpl m_type_impl; diff --git a/contrib/llvm-project/lldb/include/lldb/Core/ValueObjectRegister.h b/contrib/llvm-project/lldb/include/lldb/Core/ValueObjectRegister.h index e210b36d2a45..20a7411b6fde 100644 --- a/contrib/llvm-project/lldb/include/lldb/Core/ValueObjectRegister.h +++ b/contrib/llvm-project/lldb/include/lldb/Core/ValueObjectRegister.h @@ -84,7 +84,7 @@ public: static lldb::ValueObjectSP Create(ExecutionContextScope *exe_scope, lldb::RegisterContextSP ®_ctx_sp, - uint32_t reg_num); + const RegisterInfo *reg_info); llvm::Optional<uint64_t> GetByteSize() override; @@ -119,15 +119,16 @@ protected: CompilerType m_compiler_type; private: - void ConstructObject(uint32_t reg_num); + void ConstructObject(const RegisterInfo *reg_info); friend class ValueObjectRegisterSet; ValueObjectRegister(ValueObject &parent, lldb::RegisterContextSP ®_ctx_sp, - uint32_t reg_num); + const RegisterInfo *reg_info); ValueObjectRegister(ExecutionContextScope *exe_scope, ValueObjectManager &manager, - lldb::RegisterContextSP ®_ctx_sp, uint32_t reg_num); + lldb::RegisterContextSP ®_ctx_sp, + const RegisterInfo *reg_info); // For ValueObject only ValueObjectRegister(const ValueObjectRegister &) = delete; diff --git a/contrib/llvm-project/lldb/include/lldb/DataFormatters/FormattersHelpers.h b/contrib/llvm-project/lldb/include/lldb/DataFormatters/FormattersHelpers.h index 892807063b9c..4f8f0e8455cd 100644 --- a/contrib/llvm-project/lldb/include/lldb/DataFormatters/FormattersHelpers.h +++ b/contrib/llvm-project/lldb/include/lldb/DataFormatters/FormattersHelpers.h @@ -56,7 +56,7 @@ void AddFilter(TypeCategoryImpl::SharedPointer category_sp, size_t ExtractIndexFromString(const char *item_name); -lldb::addr_t GetArrayAddressOrPointerValue(ValueObject &valobj); +Address GetArrayAddressOrPointerValue(ValueObject &valobj); lldb::ValueObjectSP GetValueOfLibCXXCompressedPair(ValueObject &pair); diff --git a/contrib/llvm-project/lldb/include/lldb/DataFormatters/StringPrinter.h b/contrib/llvm-project/lldb/include/lldb/DataFormatters/StringPrinter.h index 4a6e2e9051bf..4169f53e63f3 100644 --- a/contrib/llvm-project/lldb/include/lldb/DataFormatters/StringPrinter.h +++ b/contrib/llvm-project/lldb/include/lldb/DataFormatters/StringPrinter.h @@ -12,9 +12,9 @@ #include <functional> #include <string> -#include "lldb/lldb-forward.h" - +#include "lldb/Core/Address.h" #include "lldb/Utility/DataExtractor.h" +#include "lldb/lldb-forward.h" namespace lldb_private { namespace formatters { @@ -105,21 +105,21 @@ public: ReadStringAndDumpToStreamOptions(ValueObject &valobj); - void SetLocation(uint64_t l) { m_location = l; } + void SetLocation(Address l) { m_location = std::move(l); } - uint64_t GetLocation() const { return m_location; } + const Address &GetLocation() const { return m_location; } - void SetProcessSP(lldb::ProcessSP p) { m_process_sp = std::move(p); } + void SetTargetSP(lldb::TargetSP t) { m_target_sp = std::move(t); } - lldb::ProcessSP GetProcessSP() const { return m_process_sp; } + lldb::TargetSP GetTargetSP() const { return m_target_sp; } void SetHasSourceSize(bool e) { m_has_source_size = e; } bool HasSourceSize() const { return m_has_source_size; } private: - uint64_t m_location = 0; - lldb::ProcessSP m_process_sp; + Address m_location; + lldb::TargetSP m_target_sp; /// True iff we know the source size of the string. bool m_has_source_size = false; }; @@ -133,9 +133,9 @@ public: ReadBufferAndDumpToStreamOptions( const ReadStringAndDumpToStreamOptions &options); - void SetData(DataExtractor d) { m_data = d; } + void SetData(DataExtractor &&d) { m_data = std::move(d); } - lldb_private::DataExtractor GetData() const { return m_data; } + const lldb_private::DataExtractor &GetData() const { return m_data; } void SetIsTruncated(bool t) { m_is_truncated = t; } diff --git a/contrib/llvm-project/lldb/include/lldb/Expression/IRExecutionUnit.h b/contrib/llvm-project/lldb/include/lldb/Expression/IRExecutionUnit.h index ad3c7372e67d..bb43851e17c9 100644 --- a/contrib/llvm-project/lldb/include/lldb/Expression/IRExecutionUnit.h +++ b/contrib/llvm-project/lldb/include/lldb/Expression/IRExecutionUnit.h @@ -214,26 +214,21 @@ private: Status DisassembleFunction(Stream &stream, lldb::ProcessSP &process_sp); - struct SearchSpec; - - void CollectCandidateCNames(std::vector<SearchSpec> &C_specs, + void CollectCandidateCNames(std::vector<ConstString> &C_names, ConstString name); - void CollectCandidateCPlusPlusNames(std::vector<SearchSpec> &CPP_specs, - const std::vector<SearchSpec> &C_specs, + void CollectCandidateCPlusPlusNames(std::vector<ConstString> &CPP_names, + const std::vector<ConstString> &C_names, const SymbolContext &sc); - void CollectFallbackNames(std::vector<SearchSpec> &fallback_specs, - const std::vector<SearchSpec> &C_specs); - - lldb::addr_t FindInSymbols(const std::vector<SearchSpec> &specs, + lldb::addr_t FindInSymbols(const std::vector<ConstString> &names, const lldb_private::SymbolContext &sc, bool &symbol_was_missing_weak); - lldb::addr_t FindInRuntimes(const std::vector<SearchSpec> &specs, + lldb::addr_t FindInRuntimes(const std::vector<ConstString> &names, const lldb_private::SymbolContext &sc); - lldb::addr_t FindInUserDefinedSymbols(const std::vector<SearchSpec> &specs, + lldb::addr_t FindInUserDefinedSymbols(const std::vector<ConstString> &names, const lldb_private::SymbolContext &sc); void ReportSymbolLookupError(ConstString name); diff --git a/contrib/llvm-project/lldb/include/lldb/Host/Config.h.cmake b/contrib/llvm-project/lldb/include/lldb/Host/Config.h.cmake index c667708a90a6..777a6d1be541 100644 --- a/contrib/llvm-project/lldb/include/lldb/Host/Config.h.cmake +++ b/contrib/llvm-project/lldb/include/lldb/Host/Config.h.cmake @@ -13,17 +13,12 @@ #cmakedefine01 LLDB_HAVE_EL_RFUNC_T - -#cmakedefine01 HAVE_SYS_TYPES_H - #cmakedefine01 HAVE_SYS_EVENT_H #cmakedefine01 HAVE_PPOLL #cmakedefine01 HAVE_PTSNAME_R -#cmakedefine01 HAVE_SIGACTION - #cmakedefine01 HAVE_PROCESS_VM_READV #cmakedefine01 HAVE_NR_PROCESS_VM_READV diff --git a/contrib/llvm-project/lldb/include/lldb/Host/File.h b/contrib/llvm-project/lldb/include/lldb/Host/File.h index d364d954a1c1..d10ec1fe282a 100644 --- a/contrib/llvm-project/lldb/include/lldb/Host/File.h +++ b/contrib/llvm-project/lldb/include/lldb/Host/File.h @@ -10,6 +10,7 @@ #define LLDB_HOST_FILE_H #include "lldb/Host/PosixApi.h" +#include "lldb/Host/Terminal.h" #include "lldb/Utility/IOObject.h" #include "lldb/Utility/Status.h" #include "lldb/lldb-private.h" @@ -39,24 +40,29 @@ public: // NB this enum is used in the lldb platform gdb-remote packet // vFile:open: and existing values cannot be modified. // - // FIXME - // These values do not match the values used by GDB + // The first set of values is defined by gdb headers and can be found + // in the documentation at: // * https://sourceware.org/gdb/onlinedocs/gdb/Open-Flags.html#Open-Flags - // * rdar://problem/46788934 + // + // The second half are LLDB extensions and use the highest uint32_t bits + // to avoid risk of collisions with future gdb remote protocol changes. enum OpenOptions : uint32_t { - eOpenOptionRead = (1u << 0), // Open file for reading - eOpenOptionWrite = (1u << 1), // Open file for writing + eOpenOptionReadOnly = 0x0, // Open file for reading (only) + eOpenOptionWriteOnly = 0x1, // Open file for writing (only) + eOpenOptionReadWrite = 0x2, // Open file for both reading and writing eOpenOptionAppend = - (1u << 2), // Don't truncate file when opening, append to end of file - eOpenOptionTruncate = (1u << 3), // Truncate file when opening - eOpenOptionNonBlocking = (1u << 4), // File reads - eOpenOptionCanCreate = (1u << 5), // Create file if doesn't already exist + 0x8, // Don't truncate file when opening, append to end of file + eOpenOptionCanCreate = 0x200, // Create file if doesn't already exist + eOpenOptionTruncate = 0x400, // Truncate file when opening eOpenOptionCanCreateNewOnly = - (1u << 6), // Can create file only if it doesn't already exist - eOpenOptionDontFollowSymlinks = (1u << 7), + 0x800, // Can create file only if it doesn't already exist + + eOpenOptionNonBlocking = (1u << 28), // File reads + eOpenOptionDontFollowSymlinks = (1u << 29), eOpenOptionCloseOnExec = - (1u << 8), // Close the file when executing a new process - LLVM_MARK_AS_BITMASK_ENUM(/* largest_value= */ eOpenOptionCloseOnExec) + (1u << 30), // Close the file when executing a new process + eOpenOptionInvalid = (1u << 31), // Used as invalid value + LLVM_MARK_AS_BITMASK_ENUM(/* largest_value= */ eOpenOptionInvalid) }; static mode_t ConvertOpenOptionsForPOSIXOpen(OpenOptions open_options); @@ -303,8 +309,8 @@ public: /// Some options like eOpenOptionDontFollowSymlinks only make /// sense when a file is being opened (or not at all) /// and may not be preserved for this method. But any valid - /// File should return either or both of eOpenOptionRead and - /// eOpenOptionWrite here. + /// File should return either eOpenOptionReadOnly, eOpenOptionWriteOnly + /// or eOpenOptionReadWrite here. /// /// \return /// OpenOptions flags for this file, or an error. @@ -428,6 +434,45 @@ private: const NativeFile &operator=(const NativeFile &) = delete; }; +class SerialPort : public NativeFile { +public: + struct Options { + llvm::Optional<unsigned int> BaudRate = llvm::None; + llvm::Optional<Terminal::Parity> Parity = llvm::None; + llvm::Optional<Terminal::ParityCheck> ParityCheck = llvm::None; + llvm::Optional<unsigned int> StopBits = llvm::None; + }; + + // Obtain Options corresponding to the passed URL query string + // (i.e. the part after '?'). + static llvm::Expected<Options> OptionsFromURL(llvm::StringRef urlqs); + + static llvm::Expected<std::unique_ptr<SerialPort>> + Create(int fd, OpenOptions options, Options serial_options, + bool transfer_ownership); + + bool IsValid() const override { + return NativeFile::IsValid() && m_is_interactive == eLazyBoolYes; + } + + Status Close() override; + + static char ID; + virtual bool isA(const void *classID) const override { + return classID == &ID || File::isA(classID); + } + static bool classof(const File *file) { return file->isA(&ID); } + +private: + SerialPort(int fd, OpenOptions options, Options serial_options, + bool transfer_ownership); + + SerialPort(const SerialPort &) = delete; + const SerialPort &operator=(const SerialPort &) = delete; + + TerminalState m_state; +}; + } // namespace lldb_private #endif // LLDB_HOST_FILE_H diff --git a/contrib/llvm-project/lldb/include/lldb/Host/MainLoop.h b/contrib/llvm-project/lldb/include/lldb/Host/MainLoop.h index 06785bbdbe24..94499f583463 100644 --- a/contrib/llvm-project/lldb/include/lldb/Host/MainLoop.h +++ b/contrib/llvm-project/lldb/include/lldb/Host/MainLoop.h @@ -95,7 +95,7 @@ private: struct SignalInfo { std::list<Callback> callbacks; -#if HAVE_SIGACTION +#ifndef SIGNAL_POLLING_UNSUPPORTED struct sigaction old_action; #endif bool was_blocked : 1; diff --git a/contrib/llvm-project/lldb/include/lldb/Host/Socket.h b/contrib/llvm-project/lldb/include/lldb/Host/Socket.h index 36db0ec63e9d..01f790ee11fb 100644 --- a/contrib/llvm-project/lldb/include/lldb/Host/Socket.h +++ b/contrib/llvm-project/lldb/include/lldb/Host/Socket.h @@ -16,7 +16,6 @@ #include "lldb/Host/SocketAddress.h" #include "lldb/Utility/IOObject.h" -#include "lldb/Utility/Predicate.h" #include "lldb/Utility/Status.h" #ifdef _WIN32 @@ -48,6 +47,15 @@ public: ProtocolUnixAbstract }; + struct HostAndPort { + std::string hostname; + uint16_t port; + + bool operator==(const HostAndPort &R) const { + return port == R.port && hostname == R.hostname; + } + }; + static const NativeSocket kInvalidSocketValue; ~Socket() override; @@ -68,7 +76,7 @@ public: // the socket after it is initialized, but before entering a blocking accept. static llvm::Expected<std::unique_ptr<TCPSocket>> TcpListen(llvm::StringRef host_and_port, bool child_processes_inherit, - Predicate<uint16_t> *predicate, int backlog = 5); + int backlog = 5); static llvm::Expected<std::unique_ptr<Socket>> TcpConnect(llvm::StringRef host_and_port, bool child_processes_inherit); @@ -76,18 +84,6 @@ public: static llvm::Expected<std::unique_ptr<UDPSocket>> UdpConnect(llvm::StringRef host_and_port, bool child_processes_inherit); - static Status UnixDomainConnect(llvm::StringRef host_and_port, - bool child_processes_inherit, - Socket *&socket); - static Status UnixDomainAccept(llvm::StringRef host_and_port, - bool child_processes_inherit, Socket *&socket); - static Status UnixAbstractConnect(llvm::StringRef host_and_port, - bool child_processes_inherit, - Socket *&socket); - static Status UnixAbstractAccept(llvm::StringRef host_and_port, - bool child_processes_inherit, - Socket *&socket); - int GetOption(int level, int option_name, int &option_value); int SetOption(int level, int option_name, int option_value); @@ -103,9 +99,8 @@ public: bool IsValid() const override { return m_socket != kInvalidSocketValue; } WaitableHandle GetWaitableHandle() override; - static bool DecodeHostAndPort(llvm::StringRef host_and_port, - std::string &host_str, std::string &port_str, - int32_t &port, Status *error_ptr); + static llvm::Expected<HostAndPort> + DecodeHostAndPort(llvm::StringRef host_and_port); // If this Socket is connected then return the URI used to connect. virtual std::string GetRemoteConnectionURI() const { return ""; }; @@ -130,6 +125,9 @@ protected: bool m_should_close_fd; }; +llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, + const Socket::HostAndPort &HP); + } // namespace lldb_private #endif // LLDB_HOST_SOCKET_H diff --git a/contrib/llvm-project/lldb/include/lldb/Host/StringConvert.h b/contrib/llvm-project/lldb/include/lldb/Host/StringConvert.h deleted file mode 100644 index 33608a85ff42..000000000000 --- a/contrib/llvm-project/lldb/include/lldb/Host/StringConvert.h +++ /dev/null @@ -1,38 +0,0 @@ -//===-- StringConvert.h -----------------------------------------*- C++ -*-===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#ifndef LLDB_HOST_STRINGCONVERT_H -#define LLDB_HOST_STRINGCONVERT_H - -#include <cstdint> - -namespace lldb_private { - -namespace StringConvert { - -/// \namespace StringConvert StringConvert.h "lldb/Host/StringConvert.h" -/// Utility classes for converting strings into Integers - -int32_t ToSInt32(const char *s, int32_t fail_value = 0, int base = 0, - bool *success_ptr = nullptr); - -uint32_t ToUInt32(const char *s, uint32_t fail_value = 0, int base = 0, - bool *success_ptr = nullptr); - -int64_t ToSInt64(const char *s, int64_t fail_value = 0, int base = 0, - bool *success_ptr = nullptr); - -uint64_t ToUInt64(const char *s, uint64_t fail_value = 0, int base = 0, - bool *success_ptr = nullptr); - -double ToDouble(const char *s, double fail_value = 0.0, - bool *success_ptr = nullptr); -} // namespace StringConvert -} // namespace lldb_private - -#endif diff --git a/contrib/llvm-project/lldb/include/lldb/Host/Terminal.h b/contrib/llvm-project/lldb/include/lldb/Host/Terminal.h index ca91d6b59720..8ff6d75657a7 100644 --- a/contrib/llvm-project/lldb/include/lldb/Host/Terminal.h +++ b/contrib/llvm-project/lldb/include/lldb/Host/Terminal.h @@ -10,15 +10,35 @@ #define LLDB_HOST_TERMINAL_H #if defined(__cplusplus) -#include "lldb/Host/Config.h" #include "lldb/lldb-private.h" - -struct termios; +#include "llvm/Support/Error.h" namespace lldb_private { +class TerminalState; + class Terminal { public: + enum class Parity { + No, + Even, + Odd, + Space, + Mark, + }; + + enum class ParityCheck { + // No parity checking + No, + // Replace erraneous bytes with NUL + ReplaceWithNUL, + // Ignore erraneous bytes + Ignore, + // Mark erraneous bytes by prepending them with \xFF\x00; real \xFF + // is escaped to \xFF\xFF + Mark, + }; + Terminal(int fd = -1) : m_fd(fd) {} ~Terminal() = default; @@ -33,25 +53,54 @@ public: void Clear() { m_fd = -1; } - bool SetEcho(bool enabled); + llvm::Error SetEcho(bool enabled); + + llvm::Error SetCanonical(bool enabled); + + llvm::Error SetRaw(); - bool SetCanonical(bool enabled); + llvm::Error SetBaudRate(unsigned int baud_rate); + + llvm::Error SetStopBits(unsigned int stop_bits); + + llvm::Error SetParity(Parity parity); + + llvm::Error SetParityCheck(ParityCheck parity_check); + + llvm::Error SetHardwareFlowControl(bool enabled); protected: + struct Data; + int m_fd; // This may or may not be a terminal file descriptor + + llvm::Expected<Data> GetData(); + llvm::Error SetData(const Data &data); + + friend class TerminalState; }; -/// \class State Terminal.h "lldb/Host/Terminal.h" -/// A terminal state saving/restoring class. +/// \class TerminalState Terminal.h "lldb/Host/Terminal.h" +/// A RAII-friendly terminal state saving/restoring class. /// /// This class can be used to remember the terminal state for a file /// descriptor and later restore that state as it originally was. class TerminalState { public: - /// Default constructor - TerminalState(); + /// Construct a new instance and optionally save terminal state. + /// + /// \param[in] term + /// The Terminal instance holding the file descriptor to save the state + /// of. If the instance is not associated with a fd, no state will + /// be saved. + /// + /// \param[in] save_process_group + /// If \b true, save the process group settings, else do not + /// save the process group settings for a TTY. + TerminalState(Terminal term = -1, bool save_process_group = false); - /// Destructor + /// Destroy the instance, restoring terminal state if saved. If restoring + /// state is undesirable, the instance needs to be reset before destruction. ~TerminalState(); /// Save the TTY state for \a fd. @@ -60,8 +109,8 @@ public: /// "save_process_group" is true, attempt to save the process group info for /// the TTY. /// - /// \param[in] fd - /// The file descriptor to save the state of. + /// \param[in] term + /// The Terminal instance holding fd to save. /// /// \param[in] save_process_group /// If \b true, save the process group settings, else do not @@ -70,7 +119,7 @@ public: /// \return /// Returns \b true if \a fd describes a TTY and if the state /// was able to be saved, \b false otherwise. - bool Save(int fd, bool save_process_group); + bool Save(Terminal term, bool save_process_group); /// Restore the TTY state to the cached state. /// @@ -115,66 +164,10 @@ protected: bool ProcessGroupIsValid() const; // Member variables - Terminal m_tty; ///< A terminal - int m_tflags = -1; ///< Cached tflags information. -#if LLDB_ENABLE_TERMIOS - std::unique_ptr<struct termios> - m_termios_up; ///< Cached terminal state information. -#endif - lldb::pid_t m_process_group = -1; ///< Cached process group information. -}; - -/// \class TerminalStateSwitcher Terminal.h "lldb/Host/Terminal.h" -/// A TTY state switching class. -/// -/// This class can be used to remember 2 TTY states for a given file -/// descriptor and switch between the two states. -class TerminalStateSwitcher { -public: - /// Constructor - TerminalStateSwitcher(); - - /// Destructor - ~TerminalStateSwitcher(); - - /// Get the number of possible states to save. - /// - /// \return - /// The number of states that this TTY switcher object contains. - uint32_t GetNumberOfStates() const; - - /// Restore the TTY state for state at index \a idx. - /// - /// \return - /// Returns \b true if the TTY state was successfully restored, - /// \b false otherwise. - bool Restore(uint32_t idx) const; - - /// Save the TTY state information for the state at index \a idx. The TTY - /// state is saved for the file descriptor \a fd and the process group - /// information will also be saved if requested by \a save_process_group. - /// - /// \param[in] idx - /// The index into the state array where the state should be - /// saved. - /// - /// \param[in] fd - /// The file descriptor for which to save the settings. - /// - /// \param[in] save_process_group - /// If \b true, save the process group information for the TTY. - /// - /// \return - /// Returns \b true if the save was successful, \b false - /// otherwise. - bool Save(uint32_t idx, int fd, bool save_process_group); - -protected: - // Member variables - mutable uint32_t m_currentState = - UINT32_MAX; ///< The currently active TTY state index. - TerminalState - m_ttystates[2]; ///< The array of TTY states that holds saved TTY info. + Terminal m_tty; ///< A terminal + int m_tflags = -1; ///< Cached tflags information. + std::unique_ptr<Terminal::Data> m_data; ///< Platform-specific implementation. + lldb::pid_t m_process_group = -1; ///< Cached process group information. }; } // namespace lldb_private diff --git a/contrib/llvm-project/lldb/include/lldb/Host/common/NativeProcessProtocol.h b/contrib/llvm-project/lldb/include/lldb/Host/common/NativeProcessProtocol.h index 770149e3fb28..7c3458527616 100644 --- a/contrib/llvm-project/lldb/include/lldb/Host/common/NativeProcessProtocol.h +++ b/contrib/llvm-project/lldb/include/lldb/Host/common/NativeProcessProtocol.h @@ -250,8 +250,9 @@ public: auxv = (1u << 4), libraries_svr4 = (1u << 5), memory_tagging = (1u << 6), + savecore = (1u << 7), - LLVM_MARK_AS_BITMASK_ENUM(memory_tagging) + LLVM_MARK_AS_BITMASK_ENUM(savecore) }; class Factory { @@ -369,6 +370,19 @@ public: m_enabled_extensions = flags; } + /// Write a core dump (without crashing the program). + /// + /// \param[in] path_hint + /// Suggested core dump path (optional, can be empty). + /// + /// \return + /// Path to the core dump if successfully written, an error + /// otherwise. + virtual llvm::Expected<std::string> SaveCore(llvm::StringRef path_hint) { + return llvm::createStringError(llvm::inconvertibleErrorCode(), + "Not implemented"); + } + protected: struct SoftwareBreakpoint { uint32_t ref_count; diff --git a/contrib/llvm-project/lldb/include/lldb/Host/freebsd/HostInfoFreeBSD.h b/contrib/llvm-project/lldb/include/lldb/Host/freebsd/HostInfoFreeBSD.h index 56f20bbd23d3..b2f3f08cd145 100644 --- a/contrib/llvm-project/lldb/include/lldb/Host/freebsd/HostInfoFreeBSD.h +++ b/contrib/llvm-project/lldb/include/lldb/Host/freebsd/HostInfoFreeBSD.h @@ -18,8 +18,7 @@ namespace lldb_private { class HostInfoFreeBSD : public HostInfoPosix { public: static llvm::VersionTuple GetOSVersion(); - static bool GetOSBuildString(std::string &s); - static bool GetOSKernelDescription(std::string &s); + static llvm::Optional<std::string> GetOSBuildString(); static FileSpec GetProgramFileSpec(); }; } diff --git a/contrib/llvm-project/lldb/include/lldb/Host/netbsd/HostInfoNetBSD.h b/contrib/llvm-project/lldb/include/lldb/Host/netbsd/HostInfoNetBSD.h index f9ad66eb2b2a..32644ce79a69 100644 --- a/contrib/llvm-project/lldb/include/lldb/Host/netbsd/HostInfoNetBSD.h +++ b/contrib/llvm-project/lldb/include/lldb/Host/netbsd/HostInfoNetBSD.h @@ -18,8 +18,7 @@ namespace lldb_private { class HostInfoNetBSD : public HostInfoPosix { public: static llvm::VersionTuple GetOSVersion(); - static bool GetOSBuildString(std::string &s); - static bool GetOSKernelDescription(std::string &s); + static llvm::Optional<std::string> GetOSBuildString(); static FileSpec GetProgramFileSpec(); }; } diff --git a/contrib/llvm-project/lldb/include/lldb/Host/openbsd/HostInfoOpenBSD.h b/contrib/llvm-project/lldb/include/lldb/Host/openbsd/HostInfoOpenBSD.h index 7ec1d5fc3606..01879ad5c0e4 100644 --- a/contrib/llvm-project/lldb/include/lldb/Host/openbsd/HostInfoOpenBSD.h +++ b/contrib/llvm-project/lldb/include/lldb/Host/openbsd/HostInfoOpenBSD.h @@ -18,8 +18,7 @@ namespace lldb_private { class HostInfoOpenBSD : public HostInfoPosix { public: static llvm::VersionTuple GetOSVersion(); - static bool GetOSBuildString(std::string &s); - static bool GetOSKernelDescription(std::string &s); + static llvm::Optional<std::string> GetOSBuildString(); static FileSpec GetProgramFileSpec(); }; } diff --git a/contrib/llvm-project/lldb/include/lldb/Host/posix/ConnectionFileDescriptorPosix.h b/contrib/llvm-project/lldb/include/lldb/Host/posix/ConnectionFileDescriptorPosix.h index 42be989dfa7b..35773d5907e9 100644 --- a/contrib/llvm-project/lldb/include/lldb/Host/posix/ConnectionFileDescriptorPosix.h +++ b/contrib/llvm-project/lldb/include/lldb/Host/posix/ConnectionFileDescriptorPosix.h @@ -16,9 +16,9 @@ #include "lldb/lldb-forward.h" #include "lldb/Host/Pipe.h" +#include "lldb/Host/Socket.h" #include "lldb/Utility/Connection.h" #include "lldb/Utility/IOObject.h" -#include "lldb/Utility/Predicate.h" namespace lldb_private { @@ -28,16 +28,8 @@ class SocketAddress; class ConnectionFileDescriptor : public Connection { public: - static const char *LISTEN_SCHEME; - static const char *ACCEPT_SCHEME; - static const char *UNIX_ACCEPT_SCHEME; - static const char *CONNECT_SCHEME; - static const char *TCP_CONNECT_SCHEME; - static const char *UDP_SCHEME; - static const char *UNIX_CONNECT_SCHEME; - static const char *UNIX_ABSTRACT_CONNECT_SCHEME; - static const char *FD_SCHEME; - static const char *FILE_SCHEME; + typedef llvm::function_ref<void(llvm::StringRef local_socket_id)> + socket_id_callback_type; ConnectionFileDescriptor(bool child_processes_inherit = false); @@ -49,7 +41,12 @@ public: bool IsConnected() const override; - lldb::ConnectionStatus Connect(llvm::StringRef s, Status *error_ptr) override; + lldb::ConnectionStatus Connect(llvm::StringRef url, + Status *error_ptr) override; + + lldb::ConnectionStatus Connect(llvm::StringRef url, + socket_id_callback_type socket_id_callback, + Status *error_ptr); lldb::ConnectionStatus Disconnect(Status *error_ptr) override; @@ -66,9 +63,7 @@ public: bool InterruptRead() override; - lldb::IOObjectSP GetReadObject() override { return m_read_sp; } - - uint16_t GetListeningPort(const Timeout<std::micro> &timeout); + lldb::IOObjectSP GetReadObject() override { return m_io_sp; } bool GetChildProcessesInherit() const; void SetChildProcessesInherit(bool child_processes_inherit); @@ -78,37 +73,68 @@ protected: void CloseCommandPipe(); - lldb::ConnectionStatus SocketListenAndAccept(llvm::StringRef host_and_port, - Status *error_ptr); + lldb::ConnectionStatus + AcceptSocket(Socket::SocketProtocol socket_protocol, + llvm::StringRef socket_name, + llvm::function_ref<void(Socket &)> post_listen_callback, + Status *error_ptr); + + lldb::ConnectionStatus ConnectSocket(Socket::SocketProtocol socket_protocol, + llvm::StringRef socket_name, + Status *error_ptr); + + lldb::ConnectionStatus AcceptTCP(llvm::StringRef host_and_port, + socket_id_callback_type socket_id_callback, + Status *error_ptr); lldb::ConnectionStatus ConnectTCP(llvm::StringRef host_and_port, + socket_id_callback_type socket_id_callback, Status *error_ptr); - lldb::ConnectionStatus ConnectUDP(llvm::StringRef args, Status *error_ptr); + lldb::ConnectionStatus ConnectUDP(llvm::StringRef args, + socket_id_callback_type socket_id_callback, + Status *error_ptr); + + lldb::ConnectionStatus + ConnectNamedSocket(llvm::StringRef socket_name, + socket_id_callback_type socket_id_callback, + Status *error_ptr); + + lldb::ConnectionStatus + AcceptNamedSocket(llvm::StringRef socket_name, + socket_id_callback_type socket_id_callback, + Status *error_ptr); + + lldb::ConnectionStatus + AcceptAbstractSocket(llvm::StringRef socket_name, + socket_id_callback_type socket_id_callback, + Status *error_ptr); - lldb::ConnectionStatus NamedSocketConnect(llvm::StringRef socket_name, - Status *error_ptr); + lldb::ConnectionStatus + ConnectAbstractSocket(llvm::StringRef socket_name, + socket_id_callback_type socket_id_callback, + Status *error_ptr); - lldb::ConnectionStatus NamedSocketAccept(llvm::StringRef socket_name, - Status *error_ptr); + lldb::ConnectionStatus ConnectFD(llvm::StringRef args, + socket_id_callback_type socket_id_callback, + Status *error_ptr); - lldb::ConnectionStatus UnixAbstractSocketConnect(llvm::StringRef socket_name, - Status *error_ptr); + lldb::ConnectionStatus ConnectFile(llvm::StringRef args, + socket_id_callback_type socket_id_callback, + Status *error_ptr); - lldb::IOObjectSP m_read_sp; - lldb::IOObjectSP m_write_sp; + lldb::ConnectionStatus + ConnectSerialPort(llvm::StringRef args, + socket_id_callback_type socket_id_callback, + Status *error_ptr); - Predicate<uint16_t> - m_port_predicate; // Used when binding to port zero to wait for the thread - // that creates the socket, binds and listens to - // resolve the port number. + lldb::IOObjectSP m_io_sp; Pipe m_pipe; std::recursive_mutex m_mutex; std::atomic<bool> m_shutting_down; // This marks that we are shutting down so // if we get woken up from // BytesAvailable to disconnect, we won't try to read again. - bool m_waiting_for_accept = false; bool m_child_processes_inherit; std::string m_uri; diff --git a/contrib/llvm-project/lldb/include/lldb/Host/posix/HostInfoPosix.h b/contrib/llvm-project/lldb/include/lldb/Host/posix/HostInfoPosix.h index 825c79f53ecb..f1ff6b860864 100644 --- a/contrib/llvm-project/lldb/include/lldb/Host/posix/HostInfoPosix.h +++ b/contrib/llvm-project/lldb/include/lldb/Host/posix/HostInfoPosix.h @@ -22,6 +22,7 @@ class HostInfoPosix : public HostInfoBase { public: static size_t GetPageSize(); static bool GetHostname(std::string &s); + static llvm::Optional<std::string> GetOSKernelDescription(); static uint32_t GetUserID(); static uint32_t GetGroupID(); diff --git a/contrib/llvm-project/lldb/include/lldb/Interpreter/CommandCompletions.h b/contrib/llvm-project/lldb/include/lldb/Interpreter/CommandCompletions.h index c80bde0e719b..c13bc4997ff3 100644 --- a/contrib/llvm-project/lldb/include/lldb/Interpreter/CommandCompletions.h +++ b/contrib/llvm-project/lldb/include/lldb/Interpreter/CommandCompletions.h @@ -13,6 +13,7 @@ #include "lldb/Core/FileSpecList.h" #include "lldb/Core/SearchFilter.h" +#include "lldb/Interpreter/Options.h" #include "lldb/Utility/CompletionRequest.h" #include "lldb/Utility/RegularExpression.h" #include "lldb/lldb-private.h" @@ -151,6 +152,15 @@ public: static void TypeCategoryNames(CommandInterpreter &interpreter, CompletionRequest &request, SearchFilter *searcher); + + /// This completer works for commands whose only arguments are a command path. + /// It isn't tied to an argument type because it completes not on a single + /// argument but on the sequence of arguments, so you have to invoke it by + /// hand. + static void + CompleteModifiableCmdPathArgs(CommandInterpreter &interpreter, + CompletionRequest &request, + OptionElementVector &opt_element_vector); }; } // namespace lldb_private diff --git a/contrib/llvm-project/lldb/include/lldb/Interpreter/CommandInterpreter.h b/contrib/llvm-project/lldb/include/lldb/Interpreter/CommandInterpreter.h index 3b3daced3e33..e6f0d5f9c4d4 100644 --- a/contrib/llvm-project/lldb/include/lldb/Interpreter/CommandInterpreter.h +++ b/contrib/llvm-project/lldb/include/lldb/Interpreter/CommandInterpreter.h @@ -231,11 +231,12 @@ public: }; enum CommandTypes { - eCommandTypesBuiltin = 0x0001, // native commands such as "frame" - eCommandTypesUserDef = 0x0002, // scripted commands - eCommandTypesAliases = 0x0004, // aliases such as "po" - eCommandTypesHidden = 0x0008, // commands prefixed with an underscore - eCommandTypesAllThem = 0xFFFF // all commands + eCommandTypesBuiltin = 0x0001, //< native commands such as "frame" + eCommandTypesUserDef = 0x0002, //< scripted commands + eCommandTypesUserMW = 0x0004, //< multiword commands (command containers) + eCommandTypesAliases = 0x0008, //< aliases such as "po" + eCommandTypesHidden = 0x0010, //< commands prefixed with an underscore + eCommandTypesAllThem = 0xFFFF //< all commands }; CommandInterpreter(Debugger &debugger, bool synchronous_execution); @@ -256,8 +257,8 @@ public: bool AddCommand(llvm::StringRef name, const lldb::CommandObjectSP &cmd_sp, bool can_replace); - bool AddUserCommand(llvm::StringRef name, const lldb::CommandObjectSP &cmd_sp, - bool can_replace); + Status AddUserCommand(llvm::StringRef name, + const lldb::CommandObjectSP &cmd_sp, bool can_replace); lldb::CommandObjectSP GetCommandSPExact(llvm::StringRef cmd, bool include_aliases = false) const; @@ -266,12 +267,49 @@ public: StringList *matches = nullptr, StringList *descriptions = nullptr) const; + CommandObject *GetUserCommandObject(llvm::StringRef cmd, + StringList *matches = nullptr, + StringList *descriptions = nullptr) const; + + /// Determine whether a root level, built-in command with this name exists. bool CommandExists(llvm::StringRef cmd) const; + /// Determine whether an alias command with this name exists bool AliasExists(llvm::StringRef cmd) const; + /// Determine whether a root-level user command with this name exists. bool UserCommandExists(llvm::StringRef cmd) const; + /// Determine whether a root-level user multiword command with this name + /// exists. + bool UserMultiwordCommandExists(llvm::StringRef cmd) const; + + /// Look up the command pointed to by path encoded in the arguments of + /// the incoming command object. If all the path components exist + /// and are all actual commands - not aliases, and the leaf command is a + /// multiword command, return the command. Otherwise return nullptr, and put + /// a useful diagnostic in the Status object. + /// + /// \param[in] path + /// An Args object holding the path in its arguments + /// \param[in] leaf_is_command + /// If true, return the container of the leaf name rather than looking up + /// the whole path as a leaf command. The leaf needn't exist in this case. + /// \param[in,out] result + /// If the path is not found, this error shows where we got off track. + /// \return + /// If found, a pointer to the CommandObjectMultiword pointed to by path, + /// or to the container of the leaf element is is_leaf_command. + /// Returns nullptr under two circumstances: + /// 1) The command in not found (check error.Fail) + /// 2) is_leaf is true and the path has only a leaf. We don't have a + /// dummy "contains everything MWC, so we return null here, but + /// in this case error.Success is true. + + CommandObjectMultiword *VerifyUserMultiwordCmdPath(Args &path, + bool leaf_is_command, + Status &result); + CommandAlias *AddAlias(llvm::StringRef alias_name, lldb::CommandObjectSP &command_obj_sp, llvm::StringRef args_string = llvm::StringRef()); @@ -283,6 +321,11 @@ public: bool GetAliasFullName(llvm::StringRef cmd, std::string &full_name) const; + bool RemoveUserMultiword(llvm::StringRef multiword_name); + + // Do we want to allow top-level user multiword commands to be deleted? + void RemoveAllUserMultiword() { m_user_mw_dict.clear(); } + bool RemoveUser(llvm::StringRef alias_name); void RemoveAllUser() { m_user_dict.clear(); } @@ -414,6 +457,8 @@ public: bool HasUserCommands() const; + bool HasUserMultiwordCommands() const; + bool HasAliasOptions() const; void BuildAliasCommandArgs(CommandObject *alias_cmd_obj, @@ -421,6 +466,7 @@ public: std::string &raw_input_string, CommandReturnObject &result); + /// Picks the number out of a string of the form "%NNN", otherwise return 0. int GetOptionArgumentPosition(const char *in_string); void SkipLLDBInitFiles(bool skip_lldbinit_files) { @@ -437,7 +483,8 @@ public: StringList &commands_help, bool search_builtin_commands, bool search_user_commands, - bool search_alias_commands); + bool search_alias_commands, + bool search_user_mw_commands); bool GetBatchCommandMode() { return m_batch_command_mode; } @@ -506,6 +553,10 @@ public: return m_user_dict; } + const CommandObject::CommandMap &GetUserMultiwordCommands() const { + return m_user_mw_dict; + } + const CommandObject::CommandMap &GetCommands() const { return m_command_dict; } @@ -636,6 +687,8 @@ private: CommandObject::CommandMap m_alias_dict; // Stores user aliases/abbreviations for commands CommandObject::CommandMap m_user_dict; // Stores user-defined commands + CommandObject::CommandMap + m_user_mw_dict; // Stores user-defined multiword commands CommandHistory m_command_history; std::string m_repeat_command; // Stores the command that will be executed for // an empty command string. diff --git a/contrib/llvm-project/lldb/include/lldb/Interpreter/CommandObject.h b/contrib/llvm-project/lldb/include/lldb/Interpreter/CommandObject.h index 8bc5d3e22355..89cc161993a9 100644 --- a/contrib/llvm-project/lldb/include/lldb/Interpreter/CommandObject.h +++ b/contrib/llvm-project/lldb/include/lldb/Interpreter/CommandObject.h @@ -145,6 +145,10 @@ public: virtual bool IsMultiwordObject() { return false; } + bool IsUserCommand() { return m_is_user_command; } + + void SetIsUserCommand(bool is_user) { m_is_user_command = is_user; } + virtual CommandObjectMultiword *GetAsMultiwordCommand() { return nullptr; } virtual bool IsAlias() { return false; } @@ -159,6 +163,10 @@ public: return lldb::CommandObjectSP(); } + virtual lldb::CommandObjectSP GetSubcommandSPExact(llvm::StringRef sub_cmd) { + return lldb::CommandObjectSP(); + } + virtual CommandObject *GetSubcommandObject(llvm::StringRef sub_cmd, StringList *matches = nullptr) { return nullptr; @@ -183,6 +191,13 @@ public: return false; } + virtual llvm::Error LoadUserSubcommand(llvm::StringRef cmd_name, + const lldb::CommandObjectSP &command_obj, + bool can_replace) { + return llvm::createStringError(llvm::inconvertibleErrorCode(), + "can only add commands to container commands"); + } + virtual bool WantsRawCommandString() = 0; // By default, WantsCompletion = !WantsRawCommandString. Subclasses who want @@ -367,6 +382,7 @@ protected: lldb::CommandOverrideCallback m_deprecated_command_override_callback; lldb::CommandOverrideCallbackWithResult m_command_override_callback; void *m_command_override_baton; + bool m_is_user_command = false; // Helper function to populate IDs or ID ranges as the command argument data // to the specified command argument entry. diff --git a/contrib/llvm-project/lldb/include/lldb/Interpreter/CommandObjectMultiword.h b/contrib/llvm-project/lldb/include/lldb/Interpreter/CommandObjectMultiword.h index f330a745f9bd..a0e8d163c4b6 100644 --- a/contrib/llvm-project/lldb/include/lldb/Interpreter/CommandObjectMultiword.h +++ b/contrib/llvm-project/lldb/include/lldb/Interpreter/CommandObjectMultiword.h @@ -35,11 +35,19 @@ public: bool LoadSubCommand(llvm::StringRef cmd_name, const lldb::CommandObjectSP &command_obj) override; + llvm::Error LoadUserSubcommand(llvm::StringRef cmd_name, + const lldb::CommandObjectSP &command_obj, + bool can_replace) override; + + llvm::Error RemoveUserSubcommand(llvm::StringRef cmd_name, bool multiword_okay); + void GenerateHelpText(Stream &output_stream) override; lldb::CommandObjectSP GetSubcommandSP(llvm::StringRef sub_cmd, StringList *matches = nullptr) override; + lldb::CommandObjectSP GetSubcommandSPExact(llvm::StringRef sub_cmd) override; + CommandObject *GetSubcommandObject(llvm::StringRef sub_cmd, StringList *matches = nullptr) override; diff --git a/contrib/llvm-project/lldb/include/lldb/Interpreter/Property.h b/contrib/llvm-project/lldb/include/lldb/Interpreter/Property.h index 97ec7ca1d4af..09f09358e8af 100644 --- a/contrib/llvm-project/lldb/include/lldb/Interpreter/Property.h +++ b/contrib/llvm-project/lldb/include/lldb/Interpreter/Property.h @@ -10,7 +10,6 @@ #define LLDB_INTERPRETER_PROPERTY_H #include "lldb/Interpreter/OptionValue.h" -#include "lldb/Utility/ConstString.h" #include "lldb/Utility/Flags.h" #include "lldb/lldb-defines.h" #include "lldb/lldb-private-types.h" @@ -37,13 +36,11 @@ class Property { public: Property(const PropertyDefinition &definition); - Property(ConstString name, ConstString desc, bool is_global, + Property(llvm::StringRef name, llvm::StringRef desc, bool is_global, const lldb::OptionValueSP &value_sp); - llvm::StringRef GetName() const { return m_name.GetStringRef(); } - llvm::StringRef GetDescription() const { - return m_description.GetStringRef(); - } + llvm::StringRef GetName() const { return m_name; } + llvm::StringRef GetDescription() const { return m_description; } const lldb::OptionValueSP &GetValue() const { return m_value_sp; } @@ -67,8 +64,8 @@ public: void SetValueChangedCallback(std::function<void()> callback); protected: - ConstString m_name; - ConstString m_description; + std::string m_name; + std::string m_description; lldb::OptionValueSP m_value_sp; bool m_is_global; }; diff --git a/contrib/llvm-project/lldb/include/lldb/Interpreter/ScriptInterpreter.h b/contrib/llvm-project/lldb/include/lldb/Interpreter/ScriptInterpreter.h index 80a054b32ce6..2b96021fffc9 100644 --- a/contrib/llvm-project/lldb/include/lldb/Interpreter/ScriptInterpreter.h +++ b/contrib/llvm-project/lldb/include/lldb/Interpreter/ScriptInterpreter.h @@ -11,6 +11,7 @@ #include "lldb/API/SBData.h" #include "lldb/API/SBError.h" +#include "lldb/API/SBMemoryRegionInfo.h" #include "lldb/Breakpoint/BreakpointOptions.h" #include "lldb/Core/Communication.h" #include "lldb/Core/PluginInterface.h" @@ -147,6 +148,8 @@ public: lldb::ScriptedProcessInterfaceUP scripted_process_interface_up = std::make_unique<ScriptedProcessInterface>()); + virtual StructuredData::DictionarySP GetInterpreterInfo(); + ~ScriptInterpreter() override = default; virtual bool Interrupt() { return false; } @@ -564,6 +567,9 @@ public: Status GetStatusFromSBError(const lldb::SBError &error) const; + llvm::Optional<MemoryRegionInfo> GetOpaqueTypeFromSBMemoryRegionInfo( + const lldb::SBMemoryRegionInfo &mem_region) const; + protected: Debugger &m_debugger; lldb::ScriptLanguage m_script_lang; diff --git a/contrib/llvm-project/lldb/include/lldb/Interpreter/ScriptedInterface.h b/contrib/llvm-project/lldb/include/lldb/Interpreter/ScriptedInterface.h new file mode 100644 index 000000000000..427fa3f4f793 --- /dev/null +++ b/contrib/llvm-project/lldb/include/lldb/Interpreter/ScriptedInterface.h @@ -0,0 +1,74 @@ +//===-- ScriptedInterface.h -------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_INTERPRETER_SCRIPTEDINTERFACE_H +#define LLDB_INTERPRETER_SCRIPTEDINTERFACE_H + +#include "lldb/Core/StructuredDataImpl.h" +#include "lldb/Target/ExecutionContext.h" +#include "lldb/Utility/Log.h" +#include "lldb/Utility/Logging.h" +#include "lldb/lldb-private.h" + +#include "llvm/Support/Compiler.h" + +#include <string> + +namespace lldb_private { +class ScriptedInterface { +public: + ScriptedInterface() = default; + virtual ~ScriptedInterface() = default; + + virtual StructuredData::GenericSP + CreatePluginObject(llvm::StringRef class_name, ExecutionContext &exe_ctx, + StructuredData::DictionarySP args_sp) = 0; + + template <typename Ret> + Ret ErrorWithMessage(llvm::StringRef caller_name, llvm::StringRef error_msg, + Status &error, + uint32_t log_caterogy = LIBLLDB_LOG_PROCESS) { + LLDB_LOGF(GetLogIfAllCategoriesSet(log_caterogy), "%s ERROR = %s", + caller_name.data(), error_msg.data()); + error.SetErrorString(llvm::Twine(caller_name + llvm::Twine(" ERROR = ") + + llvm::Twine(error_msg)) + .str()); + return {}; + } + + template <typename T = StructuredData::ObjectSP> + bool CheckStructuredDataObject(llvm::StringRef caller, T obj, Status &error) { + if (!obj) { + return ErrorWithMessage<bool>(caller, + llvm::Twine("Null StructuredData object (" + + llvm::Twine(error.AsCString()) + + llvm::Twine(").")) + .str(), + error); + } + + if (!obj->IsValid()) { + return ErrorWithMessage<bool>( + caller, + llvm::Twine("Invalid StructuredData object (" + + llvm::Twine(error.AsCString()) + llvm::Twine(").")) + .str(), + error); + } + + if (error.Fail()) + return ErrorWithMessage<bool>(caller, error.AsCString(), error); + + return true; + } + +protected: + StructuredData::GenericSP m_object_instance_sp; +}; +} // namespace lldb_private +#endif // LLDB_INTERPRETER_SCRIPTEDINTERFACE_H diff --git a/contrib/llvm-project/lldb/include/lldb/Interpreter/ScriptedProcessInterface.h b/contrib/llvm-project/lldb/include/lldb/Interpreter/ScriptedProcessInterface.h index 223e89be87ee..26fd956f96bb 100644 --- a/contrib/llvm-project/lldb/include/lldb/Interpreter/ScriptedProcessInterface.h +++ b/contrib/llvm-project/lldb/include/lldb/Interpreter/ScriptedProcessInterface.h @@ -11,20 +11,19 @@ #include "lldb/Core/StructuredDataImpl.h" #include "lldb/Interpreter/ScriptInterpreter.h" +#include "lldb/Interpreter/ScriptedInterface.h" +#include "lldb/Target/MemoryRegionInfo.h" + #include "lldb/lldb-private.h" #include <string> namespace lldb_private { -class ScriptedProcessInterface { +class ScriptedProcessInterface : virtual public ScriptedInterface { public: - ScriptedProcessInterface() : m_object_instance_sp(nullptr) {} - - virtual ~ScriptedProcessInterface() = default; - - virtual StructuredData::GenericSP - CreatePluginObject(const llvm::StringRef class_name, lldb::TargetSP target_sp, - StructuredData::DictionarySP args_sp) { + StructuredData::GenericSP + CreatePluginObject(llvm::StringRef class_name, ExecutionContext &exe_ctx, + StructuredData::DictionarySP args_sp) override { return nullptr; } @@ -36,9 +35,10 @@ public: virtual Status Stop() { return Status("ScriptedProcess did not stop"); } - virtual lldb::MemoryRegionInfoSP - GetMemoryRegionContainingAddress(lldb::addr_t address) { - return nullptr; + virtual llvm::Optional<MemoryRegionInfo> + GetMemoryRegionContainingAddress(lldb::addr_t address, Status &error) { + error.SetErrorString("ScriptedProcess have no memory region."); + return {}; } virtual StructuredData::DictionarySP GetThreadWithID(lldb::tid_t tid) { @@ -60,8 +60,44 @@ public: virtual bool IsAlive() { return true; } -private: - StructuredData::ObjectSP m_object_instance_sp; + virtual llvm::Optional<std::string> GetScriptedThreadPluginName() { + return llvm::None; + } + +protected: + friend class ScriptedThread; + virtual lldb::ScriptedThreadInterfaceSP GetScriptedThreadInterface() { + return nullptr; + } + + lldb::ScriptedThreadInterfaceSP m_scripted_thread_interface_sp = nullptr; +}; + +class ScriptedThreadInterface : virtual public ScriptedInterface { +public: + StructuredData::GenericSP + CreatePluginObject(llvm::StringRef class_name, ExecutionContext &exe_ctx, + StructuredData::DictionarySP args_sp) override { + return nullptr; + } + + virtual lldb::tid_t GetThreadID() { return LLDB_INVALID_THREAD_ID; } + + virtual llvm::Optional<std::string> GetName() { return llvm::None; } + + virtual lldb::StateType GetState() { return lldb::eStateInvalid; } + + virtual llvm::Optional<std::string> GetQueue() { return llvm::None; } + + virtual StructuredData::DictionarySP GetStopReason() { return nullptr; } + + virtual StructuredData::ArraySP GetStackFrames() { return nullptr; } + + virtual StructuredData::DictionarySP GetRegisterInfo() { return nullptr; } + + virtual llvm::Optional<std::string> GetRegisterContext() { + return llvm::None; + } }; } // namespace lldb_private diff --git a/contrib/llvm-project/lldb/include/lldb/Symbol/Block.h b/contrib/llvm-project/lldb/include/lldb/Symbol/Block.h index de94556d3f22..02fd2add5310 100644 --- a/contrib/llvm-project/lldb/include/lldb/Symbol/Block.h +++ b/contrib/llvm-project/lldb/include/lldb/Symbol/Block.h @@ -338,6 +338,8 @@ public: Block *FindBlockByID(lldb::user_id_t block_id); + Block *FindInnermostBlockByOffset(const lldb::addr_t offset); + size_t GetNumRanges() const { return m_ranges.GetSize(); } bool GetRangeContainingOffset(const lldb::addr_t offset, Range &range); diff --git a/contrib/llvm-project/lldb/include/lldb/Symbol/CompileUnit.h b/contrib/llvm-project/lldb/include/lldb/Symbol/CompileUnit.h index 2e52bca7097c..34e34e5514df 100644 --- a/contrib/llvm-project/lldb/include/lldb/Symbol/CompileUnit.h +++ b/contrib/llvm-project/lldb/include/lldb/Symbol/CompileUnit.h @@ -332,6 +332,7 @@ public: void SetLineTable(LineTable *line_table); void SetSupportFiles(const FileSpecList &support_files); + void SetSupportFiles(FileSpecList &&support_files); void SetDebugMacros(const DebugMacrosSP &debug_macros); @@ -442,6 +443,7 @@ private: CompileUnit(const CompileUnit &) = delete; const CompileUnit &operator=(const CompileUnit &) = delete; + const char *GetCachedLanguage() const; }; } // namespace lldb_private diff --git a/contrib/llvm-project/lldb/include/lldb/Symbol/SymbolFile.h b/contrib/llvm-project/lldb/include/lldb/Symbol/SymbolFile.h index ffdbdc6853f7..9ab63cac56dd 100644 --- a/contrib/llvm-project/lldb/include/lldb/Symbol/SymbolFile.h +++ b/contrib/llvm-project/lldb/include/lldb/Symbol/SymbolFile.h @@ -19,6 +19,7 @@ #include "lldb/Symbol/Type.h" #include "lldb/Symbol/TypeList.h" #include "lldb/Symbol/TypeSystem.h" +#include "lldb/Target/Statistics.h" #include "lldb/Utility/XcodeSDK.h" #include "lldb/lldb-private.h" #include "llvm/ADT/DenseSet.h" @@ -299,6 +300,38 @@ public: virtual void Dump(Stream &s); + /// Metrics gathering functions + + /// Return the size in bytes of all debug information in the symbol file. + /// + /// If the debug information is contained in sections of an ObjectFile, then + /// this call should add the size of all sections that contain debug + /// information. Symbols the symbol tables are not considered debug + /// information for this call to make it easy and quick for this number to be + /// calculated. If the symbol file is all debug information, the size of the + /// entire file should be returned. The default implementation of this + /// function will iterate over all sections in a module and add up their + /// debug info only section byte sizes. + virtual uint64_t GetDebugInfoSize(); + + /// Return the time taken to parse the debug information. + /// + /// \returns 0.0 if no information has been parsed or if there is + /// no computational cost to parsing the debug information. + virtual StatsDuration GetDebugInfoParseTime() { + return StatsDuration(0.0); + } + + /// Return the time it took to index the debug information in the object + /// file. + /// + /// \returns 0.0 if the file doesn't need to be indexed or if it + /// hasn't been indexed yet, or a valid duration if it has. + virtual StatsDuration GetDebugInfoIndexTime() { + return StatsDuration(0.0); + } + + protected: void AssertModuleLock(); virtual uint32_t CalculateNumCompileUnits() = 0; diff --git a/contrib/llvm-project/lldb/include/lldb/Symbol/SymbolVendor.h b/contrib/llvm-project/lldb/include/lldb/Symbol/SymbolVendor.h index 5c785e8c5a85..b060ac95b75a 100644 --- a/contrib/llvm-project/lldb/include/lldb/Symbol/SymbolVendor.h +++ b/contrib/llvm-project/lldb/include/lldb/Symbol/SymbolVendor.h @@ -41,9 +41,7 @@ public: SymbolFile *GetSymbolFile() { return m_sym_file_up.get(); } // PluginInterface protocol - ConstString GetPluginName() override; - - uint32_t GetPluginVersion() override; + llvm::StringRef GetPluginName() override { return "vendor-default"; } protected: std::unique_ptr<SymbolFile> m_sym_file_up; // A single symbol file. Subclasses diff --git a/contrib/llvm-project/lldb/include/lldb/Symbol/TypeSystem.h b/contrib/llvm-project/lldb/include/lldb/Symbol/TypeSystem.h index a37c1040b16e..be5783596897 100644 --- a/contrib/llvm-project/lldb/include/lldb/Symbol/TypeSystem.h +++ b/contrib/llvm-project/lldb/include/lldb/Symbol/TypeSystem.h @@ -91,7 +91,6 @@ public: virtual SymbolFile *GetSymbolFile() const { return m_sym_file; } - // Returns true if the symbol file changed during the set accessor. virtual void SetSymbolFile(SymbolFile *sym_file) { m_sym_file = sym_file; } // CompilerDecl functions @@ -392,6 +391,12 @@ public: lldb::opaque_compiler_type_t type, Stream *s, lldb::DescriptionLevel level = lldb::eDescriptionLevelFull) = 0; + /// Dump a textual representation of the internal TypeSystem state to the + /// given stream. + /// + /// This should not modify the state of the TypeSystem if possible. + virtual void Dump(llvm::raw_ostream &output) = 0; + // TODO: These methods appear unused. Should they be removed? virtual bool IsRuntimeGeneratedType(lldb::opaque_compiler_type_t type) = 0; diff --git a/contrib/llvm-project/lldb/include/lldb/Target/ABI.h b/contrib/llvm-project/lldb/include/lldb/Target/ABI.h index 8fbb6aae68c4..8ac6003554d5 100644 --- a/contrib/llvm-project/lldb/include/lldb/Target/ABI.h +++ b/contrib/llvm-project/lldb/include/lldb/Target/ABI.h @@ -11,6 +11,7 @@ #include "lldb/Core/PluginInterface.h" #include "lldb/Symbol/UnwindPlan.h" +#include "lldb/Target/DynamicRegisterInfo.h" #include "lldb/Utility/Status.h" #include "lldb/lldb-private.h" @@ -127,7 +128,8 @@ public: llvm::MCRegisterInfo &GetMCRegisterInfo() { return *m_mc_register_info_up; } - virtual void AugmentRegisterInfo(RegisterInfo &info) = 0; + virtual void + AugmentRegisterInfo(std::vector<DynamicRegisterInfo::Register> ®s) = 0; virtual bool GetPointerReturnRegister(const char *&name) { return false; } @@ -159,7 +161,8 @@ private: class RegInfoBasedABI : public ABI { public: - void AugmentRegisterInfo(RegisterInfo &info) override; + void AugmentRegisterInfo( + std::vector<DynamicRegisterInfo::Register> ®s) override; protected: using ABI::ABI; @@ -171,12 +174,14 @@ protected: class MCBasedABI : public ABI { public: - void AugmentRegisterInfo(RegisterInfo &info) override; + void AugmentRegisterInfo( + std::vector<DynamicRegisterInfo::Register> ®s) override; /// If the register name is of the form "<from_prefix>[<number>]" then change /// the name to "<to_prefix>[<number>]". Otherwise, leave the name unchanged. static void MapRegisterName(std::string ®, llvm::StringRef from_prefix, - llvm::StringRef to_prefix); + llvm::StringRef to_prefix); + protected: using ABI::ABI; diff --git a/contrib/llvm-project/lldb/include/lldb/Target/AppleArm64ExceptionClass.def b/contrib/llvm-project/lldb/include/lldb/Target/AppleArm64ExceptionClass.def new file mode 100644 index 000000000000..9a938c3b302c --- /dev/null +++ b/contrib/llvm-project/lldb/include/lldb/Target/AppleArm64ExceptionClass.def @@ -0,0 +1,50 @@ +/*===-- AppleArm64ExceptionClass.def ---------------------------*- C++ -*-=== *\ +|* +|* Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +|* See https://llvm.org/LICENSE.txt for license information. +|* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +|* +\*===----------------------------------------------------------------------===*/ + +// Defines ESR exception classes for Apple arm64* targets. +// These largely map 1:1 to the exception classes defined in ARM's architecture +// reference manual, but there are some Apple-specific additions. + +#ifndef APPLE_ARM64_EXCEPTION_CLASS +#error "APPLE_ARM64_EXCEPTION_CLASS(Name, Code) not defined." +#endif + +APPLE_ARM64_EXCEPTION_CLASS(ESR_EC_UNCATEGORIZED, 0x00) +APPLE_ARM64_EXCEPTION_CLASS(ESR_EC_WFI_WFE, 0x01) +APPLE_ARM64_EXCEPTION_CLASS(ESR_EC_MCR_MRC_CP15_TRAP, 0x03) +APPLE_ARM64_EXCEPTION_CLASS(ESR_EC_MCRR_MRRC_CP15_TRAP, 0x04) +APPLE_ARM64_EXCEPTION_CLASS(ESR_EC_MCR_MRC_CP14_TRAP, 0x05) +APPLE_ARM64_EXCEPTION_CLASS(ESR_EC_LDC_STC_CP14_TRAP, 0x06) +APPLE_ARM64_EXCEPTION_CLASS(ESR_EC_TRAP_SIMD_FP, 0x07) +APPLE_ARM64_EXCEPTION_CLASS(ESR_EC_PTRAUTH_INSTR_TRAP, 0x09) +APPLE_ARM64_EXCEPTION_CLASS(ESR_EC_MCRR_MRRC_CP14_TRAP, 0x0c) +APPLE_ARM64_EXCEPTION_CLASS(ESR_EC_ILLEGAL_INSTR_SET, 0x0e) +APPLE_ARM64_EXCEPTION_CLASS(ESR_EC_SVC_32, 0x11) +APPLE_ARM64_EXCEPTION_CLASS(ESR_EC_SVC_64, 0x15) +APPLE_ARM64_EXCEPTION_CLASS(ESR_EC_MSR_TRAP, 0x18) +APPLE_ARM64_EXCEPTION_CLASS(ESR_EC_PAC_FAIL, 0x1C) +APPLE_ARM64_EXCEPTION_CLASS(ESR_EC_IABORT_EL0, 0x20) +APPLE_ARM64_EXCEPTION_CLASS(ESR_EC_IABORT_EL1, 0x21) +APPLE_ARM64_EXCEPTION_CLASS(ESR_EC_PC_ALIGN, 0x22) +APPLE_ARM64_EXCEPTION_CLASS(ESR_EC_DABORT_EL0, 0x24) +APPLE_ARM64_EXCEPTION_CLASS(ESR_EC_DABORT_EL1, 0x25) +APPLE_ARM64_EXCEPTION_CLASS(ESR_EC_SP_ALIGN, 0x26) +APPLE_ARM64_EXCEPTION_CLASS(ESR_EC_FLOATING_POINT_32, 0x28) +APPLE_ARM64_EXCEPTION_CLASS(ESR_EC_FLOATING_POINT_64, 0x2C) +APPLE_ARM64_EXCEPTION_CLASS(ESR_EC_SERROR_INTERRUPT, 0x2F) +APPLE_ARM64_EXCEPTION_CLASS(ESR_EC_BKPT_REG_MATCH_EL0, 0x30) +APPLE_ARM64_EXCEPTION_CLASS(ESR_EC_BKPT_REG_MATCH_EL1, 0x31) +APPLE_ARM64_EXCEPTION_CLASS(ESR_EC_SW_STEP_DEBUG_EL0, 0x32) +APPLE_ARM64_EXCEPTION_CLASS(ESR_EC_SW_STEP_DEBUG_EL1, 0x33) +APPLE_ARM64_EXCEPTION_CLASS(ESR_EC_WATCHPT_MATCH_EL0, 0x34) +APPLE_ARM64_EXCEPTION_CLASS(ESR_EC_WATCHPT_MATCH_EL1, 0x35) +APPLE_ARM64_EXCEPTION_CLASS(ESR_EC_BKPT_AARCH32, 0x38) +APPLE_ARM64_EXCEPTION_CLASS(ESR_EC_BRK_AARCH64, 0x3C) +APPLE_ARM64_EXCEPTION_CLASS(ESR_EC_PRIV, 0x3F) + +#undef APPLE_ARM64_EXCEPTION_CLASS diff --git a/contrib/llvm-project/lldb/include/lldb/Target/AppleArm64ExceptionClass.h b/contrib/llvm-project/lldb/include/lldb/Target/AppleArm64ExceptionClass.h new file mode 100644 index 000000000000..95f58ee081ab --- /dev/null +++ b/contrib/llvm-project/lldb/include/lldb/Target/AppleArm64ExceptionClass.h @@ -0,0 +1,50 @@ +//===-- AppleArm64ExceptionClass.h ------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_TARGET_APPLEARM64EXCEPTIONCLASS_H +#define LLDB_TARGET_APPLEARM64EXCEPTIONCLASS_H + +#include <cstdint> + +namespace lldb_private { + +enum class AppleArm64ExceptionClass : unsigned { +#define APPLE_ARM64_EXCEPTION_CLASS(Name, Code) Name = Code, +#include "AppleArm64ExceptionClass.def" +}; + +/// Get the Apple ARM64 exception class encoded within \p esr. +inline AppleArm64ExceptionClass getAppleArm64ExceptionClass(uint32_t esr) { + /* + * Exception Syndrome Register + * + * 31 26 25 24 0 + * +------+--+------------------+ + * | EC |IL| ISS | + * +------+--+------------------+ + * + * EC - Exception Class + * IL - Instruction Length + * ISS - Instruction Specific Syndrome + */ + return static_cast<AppleArm64ExceptionClass>(esr >> 26); +} + +inline const char *toString(AppleArm64ExceptionClass EC) { + switch (EC) { +#define APPLE_ARM64_EXCEPTION_CLASS(Name, Code) \ + case AppleArm64ExceptionClass::Name: \ + return #Name; +#include "AppleArm64ExceptionClass.def" + } + return "Unknown Exception Class"; +} + +} // namespace lldb_private + +#endif // LLDB_TARGET_APPLEARM64EXCEPTIONCLASS_H diff --git a/contrib/llvm-project/lldb/include/lldb/Target/DynamicLoader.h b/contrib/llvm-project/lldb/include/lldb/Target/DynamicLoader.h index a904fac0c779..84ad0f11fabb 100644 --- a/contrib/llvm-project/lldb/include/lldb/Target/DynamicLoader.h +++ b/contrib/llvm-project/lldb/include/lldb/Target/DynamicLoader.h @@ -62,8 +62,9 @@ public: /// /// \param[in] plugin_name /// An optional name of a specific dynamic loader plug-in that - /// should be used. If NULL, pick the best plug-in. - static DynamicLoader *FindPlugin(Process *process, const char *plugin_name); + /// should be used. If empty, pick the best plug-in. + static DynamicLoader *FindPlugin(Process *process, + llvm::StringRef plugin_name); /// Construct with a process. DynamicLoader(Process *process); diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.h b/contrib/llvm-project/lldb/include/lldb/Target/DynamicRegisterInfo.h index 7e90454c6d9d..20f442529da8 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.h +++ b/contrib/llvm-project/lldb/include/lldb/Target/DynamicRegisterInfo.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_DYNAMICREGISTERINFO_H -#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_DYNAMICREGISTERINFO_H +#ifndef LLDB_TARGET_DYNAMICREGISTERINFO_H +#define LLDB_TARGET_DYNAMICREGISTERINFO_H #include <map> #include <vector> @@ -16,12 +16,31 @@ #include "lldb/Utility/StructuredData.h" #include "lldb/lldb-private.h" +namespace lldb_private { + class DynamicRegisterInfo { protected: DynamicRegisterInfo(DynamicRegisterInfo &) = default; DynamicRegisterInfo &operator=(DynamicRegisterInfo &) = default; public: + struct Register { + ConstString name; + ConstString alt_name; + ConstString set_name; + uint32_t byte_size = LLDB_INVALID_INDEX32; + uint32_t byte_offset = LLDB_INVALID_INDEX32; + lldb::Encoding encoding = lldb::eEncodingUint; + lldb::Format format = lldb::eFormatHex; + uint32_t regnum_dwarf = LLDB_INVALID_REGNUM; + uint32_t regnum_ehframe = LLDB_INVALID_REGNUM; + uint32_t regnum_generic = LLDB_INVALID_REGNUM; + uint32_t regnum_remote = LLDB_INVALID_REGNUM; + std::vector<uint32_t> value_regs; + std::vector<uint32_t> invalidate_regs; + uint32_t value_reg_offset = 0; + }; + DynamicRegisterInfo() = default; DynamicRegisterInfo(const lldb_private::StructuredData::Dictionary &dict, @@ -35,12 +54,8 @@ public: size_t SetRegisterInfo(const lldb_private::StructuredData::Dictionary &dict, const lldb_private::ArchSpec &arch); - void AddRegister(lldb_private::RegisterInfo ®_info, - lldb_private::ConstString ®_name, - lldb_private::ConstString ®_alt_name, - lldb_private::ConstString &set_name); - - void Finalize(const lldb_private::ArchSpec &arch); + size_t SetRegisterInfo(std::vector<Register> &®s, + const lldb_private::ArchSpec &arch); size_t GetNumRegisters() const; @@ -50,11 +65,9 @@ public: const lldb_private::RegisterInfo *GetRegisterInfoAtIndex(uint32_t i) const; - lldb_private::RegisterInfo *GetRegisterInfoAtIndex(uint32_t i); - const lldb_private::RegisterSet *GetRegisterSet(uint32_t i) const; - uint32_t GetRegisterSetIndexByName(lldb_private::ConstString &set_name, + uint32_t GetRegisterSetIndexByName(const lldb_private::ConstString &set_name, bool can_create); uint32_t ConvertRegisterKindToRegisterNumber(uint32_t kind, @@ -72,19 +85,34 @@ public: const lldb_private::RegisterInfo * GetRegisterInfo(llvm::StringRef reg_name) const; + typedef std::vector<lldb_private::RegisterInfo> reg_collection; + llvm::iterator_range<reg_collection::const_iterator> registers() const { + return llvm::iterator_range<reg_collection::const_iterator>(m_regs); + } + protected: // Classes that inherit from DynamicRegisterInfo can see and modify these - typedef std::vector<lldb_private::RegisterInfo> reg_collection; typedef std::vector<lldb_private::RegisterSet> set_collection; 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; - typedef std::vector<uint8_t> dwarf_opcode; - typedef std::map<uint32_t, dwarf_opcode> dynamic_reg_size_map; + typedef std::map<uint32_t, uint32_t> reg_offset_map; + + llvm::Expected<uint32_t> ByteOffsetFromSlice(uint32_t index, + llvm::StringRef slice_str, + lldb::ByteOrder byte_order); + llvm::Expected<uint32_t> ByteOffsetFromComposite( + uint32_t index, lldb_private::StructuredData::Array &composite_reg_list, + lldb::ByteOrder byte_order); + llvm::Expected<uint32_t> ByteOffsetFromRegInfoDict( + uint32_t index, lldb_private::StructuredData::Dictionary ®_info_dict, + lldb::ByteOrder byte_order); void MoveFrom(DynamicRegisterInfo &&info); + void Finalize(const lldb_private::ArchSpec &arch); + void ConfigureOffsets(); reg_collection m_regs; @@ -93,10 +121,16 @@ protected: name_collection m_set_names; reg_to_regs_map m_value_regs_map; reg_to_regs_map m_invalidate_regs_map; - dynamic_reg_size_map m_dynamic_reg_size_map; + reg_offset_map m_value_reg_offset_map; size_t m_reg_data_byte_size = 0u; // The number of bytes required to store // all registers bool m_finalized = false; bool m_is_reconfigurable = false; }; -#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_DYNAMICREGISTERINFO_H + +void addSupplementaryRegister(std::vector<DynamicRegisterInfo::Register> ®s, + DynamicRegisterInfo::Register new_reg_info); + +} // namespace lldb_private + +#endif // LLDB_TARGET_DYNAMICREGISTERINFO_H diff --git a/contrib/llvm-project/lldb/include/lldb/Target/Language.h b/contrib/llvm-project/lldb/include/lldb/Target/Language.h index 11b9daa38945..0b0891c14029 100644 --- a/contrib/llvm-project/lldb/include/lldb/Target/Language.h +++ b/contrib/llvm-project/lldb/include/lldb/Target/Language.h @@ -243,6 +243,14 @@ public: FunctionNameRepresentation representation, Stream &s); + virtual ConstString + GetDemangledFunctionNameWithoutArguments(Mangled mangled) const { + if (ConstString demangled = mangled.GetDemangledName()) + return demangled; + + return mangled.GetMangledName(); + } + virtual void GetExceptionResolverDescription(bool catch_on, bool throw_on, Stream &s); @@ -285,6 +293,19 @@ public: static LanguageSet GetLanguagesSupportingTypeSystemsForExpressions(); static LanguageSet GetLanguagesSupportingREPLs(); + // Given a mangled function name, calculates some alternative manglings since + // the compiler mangling may not line up with the symbol we are expecting. + virtual std::vector<ConstString> + GenerateAlternateFunctionManglings(const ConstString mangled) const { + return std::vector<ConstString>(); + } + + virtual ConstString + FindBestAlternateFunctionMangledName(const Mangled mangled, + const SymbolContext &sym_ctx) const { + return ConstString(); + } + protected: // Classes that inherit from Language can see and modify these diff --git a/contrib/llvm-project/lldb/include/lldb/Target/MemoryRegionInfo.h b/contrib/llvm-project/lldb/include/lldb/Target/MemoryRegionInfo.h index bc5ced64cc21..eb56ca0ea131 100644 --- a/contrib/llvm-project/lldb/include/lldb/Target/MemoryRegionInfo.h +++ b/contrib/llvm-project/lldb/include/lldb/Target/MemoryRegionInfo.h @@ -28,10 +28,10 @@ public: MemoryRegionInfo(RangeType range, OptionalBool read, OptionalBool write, OptionalBool execute, OptionalBool mapped, ConstString name, OptionalBool flash, lldb::offset_t blocksize, - OptionalBool memory_tagged) + OptionalBool memory_tagged, OptionalBool stack_memory) : m_range(range), m_read(read), m_write(write), m_execute(execute), m_mapped(mapped), m_name(name), m_flash(flash), m_blocksize(blocksize), - m_memory_tagged(memory_tagged) {} + m_memory_tagged(memory_tagged), m_is_stack_memory(stack_memory) {} RangeType &GetRange() { return m_range; } @@ -98,7 +98,8 @@ public: m_mapped == rhs.m_mapped && m_name == rhs.m_name && m_flash == rhs.m_flash && m_blocksize == rhs.m_blocksize && m_memory_tagged == rhs.m_memory_tagged && - m_pagesize == rhs.m_pagesize; + m_pagesize == rhs.m_pagesize && + m_is_stack_memory == rhs.m_is_stack_memory; } bool operator!=(const MemoryRegionInfo &rhs) const { return !(*this == rhs); } @@ -116,6 +117,10 @@ public: return m_dirty_pages; } + OptionalBool IsStackMemory() const { return m_is_stack_memory; } + + void SetIsStackMemory(OptionalBool val) { m_is_stack_memory = val; } + void SetPageSize(int pagesize) { m_pagesize = pagesize; } void SetDirtyPageList(std::vector<lldb::addr_t> pagelist) { @@ -134,6 +139,7 @@ protected: OptionalBool m_flash = eDontKnow; lldb::offset_t m_blocksize = 0; OptionalBool m_memory_tagged = eDontKnow; + OptionalBool m_is_stack_memory = eDontKnow; int m_pagesize = 0; llvm::Optional<std::vector<lldb::addr_t>> m_dirty_pages; }; diff --git a/contrib/llvm-project/lldb/include/lldb/Target/PathMappingList.h b/contrib/llvm-project/lldb/include/lldb/Target/PathMappingList.h index d788d120c47e..f1cc779ea50f 100644 --- a/contrib/llvm-project/lldb/include/lldb/Target/PathMappingList.h +++ b/contrib/llvm-project/lldb/include/lldb/Target/PathMappingList.h @@ -32,8 +32,7 @@ public: const PathMappingList &operator=(const PathMappingList &rhs); - void Append(ConstString path, ConstString replacement, - bool notify); + void Append(llvm::StringRef path, llvm::StringRef replacement, bool notify); void Append(const PathMappingList &rhs, bool notify); @@ -49,17 +48,16 @@ public: bool GetPathsAtIndex(uint32_t idx, ConstString &path, ConstString &new_path) const; - void Insert(ConstString path, ConstString replacement, + void Insert(llvm::StringRef path, llvm::StringRef replacement, uint32_t insert_idx, bool notify); bool Remove(size_t index, bool notify); bool Remove(ConstString path, bool notify); - bool Replace(ConstString path, ConstString replacement, - bool notify); + bool Replace(llvm::StringRef path, llvm::StringRef replacement, bool notify); - bool Replace(ConstString path, ConstString replacement, + bool Replace(llvm::StringRef path, llvm::StringRef replacement, uint32_t index, bool notify); bool RemapPath(ConstString path, ConstString &new_path) const; @@ -104,7 +102,7 @@ public: /// The newly remapped filespec that is guaranteed to exist. llvm::Optional<FileSpec> FindFile(const FileSpec &orig_spec) const; - uint32_t FindIndexForPath(ConstString path) const; + uint32_t FindIndexForPath(llvm::StringRef path) const; uint32_t GetModificationID() const { return m_mod_id; } diff --git a/contrib/llvm-project/lldb/include/lldb/Target/Platform.h b/contrib/llvm-project/lldb/include/lldb/Target/Platform.h index df46466655c3..956b29e45dba 100644 --- a/contrib/llvm-project/lldb/include/lldb/Target/Platform.h +++ b/contrib/llvm-project/lldb/include/lldb/Target/Platform.h @@ -55,7 +55,6 @@ private: void SetDefaultModuleCacheDirectory(const FileSpec &dir_spec); }; -typedef std::shared_ptr<PlatformProperties> PlatformPropertiesSP; typedef llvm::SmallVector<lldb::addr_t, 6> MmapArgList; /// \class Platform Platform.h "lldb/Target/Platform.h" @@ -74,8 +73,6 @@ public: /// Default Constructor Platform(bool is_host_platform); - /// Destructor. - /// /// The destructor is virtual since this class is designed to be inherited /// from by the plug-in instance. ~Platform() override; @@ -84,7 +81,7 @@ public: static void Terminate(); - static const PlatformPropertiesSP &GetGlobalPlatformProperties(); + static PlatformProperties &GetGlobalPlatformProperties(); /// Get the native host platform plug-in. /// @@ -215,9 +212,9 @@ public: bool SetOSVersion(llvm::VersionTuple os_version); - bool GetOSBuildString(std::string &s); + llvm::Optional<std::string> GetOSBuildString(); - bool GetOSKernelDescription(std::string &s); + llvm::Optional<std::string> GetOSKernelDescription(); // Returns the name of the platform ConstString GetName(); @@ -226,7 +223,7 @@ public: virtual ConstString GetFullNameForDylib(ConstString basename); - virtual const char *GetDescription() = 0; + virtual llvm::StringRef GetDescription() = 0; /// Report the current status for this platform. /// @@ -243,14 +240,12 @@ public: // HostInfo::GetOSVersion(). virtual bool GetRemoteOSVersion() { return false; } - virtual bool GetRemoteOSBuildString(std::string &s) { - s.clear(); - return false; + virtual llvm::Optional<std::string> GetRemoteOSBuildString() { + return llvm::None; } - virtual bool GetRemoteOSKernelDescription(std::string &s) { - s.clear(); - return false; + virtual llvm::Optional<std::string> GetRemoteOSKernelDescription() { + return llvm::None; } // Remote Platform subclasses need to override this function @@ -327,7 +322,13 @@ public: /// \b true if \a arch was filled in and is valid, \b false /// otherwise. virtual bool GetSupportedArchitectureAtIndex(uint32_t idx, - ArchSpec &arch) = 0; + ArchSpec &arch); + + /// Get the platform's supported architectures in the order in which they + /// should be searched. + /// NB: This implementation is mutually recursive with + /// GetSupportedArchitectureAtIndex. Subclasses should implement one of them. + virtual std::vector<ArchSpec> GetSupportedArchitectures(); virtual size_t GetSoftwareBreakpointTrapOpcode(Target &target, BreakpointSite *bp_site); @@ -363,11 +364,9 @@ public: /// platforms will want to subclass this function in order to be able to /// intercept STDIO and possibly launch a separate process that will debug /// the debuggee. - virtual lldb::ProcessSP - DebugProcess(ProcessLaunchInfo &launch_info, Debugger &debugger, - Target *target, // Can be nullptr, if nullptr create a new - // target, else use existing one - Status &error); + virtual lldb::ProcessSP DebugProcess(ProcessLaunchInfo &launch_info, + Debugger &debugger, Target &target, + Status &error); virtual lldb::ProcessSP ConnectProcess(llvm::StringRef connect_url, llvm::StringRef plugin_name, @@ -726,6 +725,24 @@ public: /// A list of symbol names. The list may be empty. virtual const std::vector<ConstString> &GetTrapHandlerSymbolNames(); + /// Try to get a specific unwind plan for a named trap handler. + /// The default is not to have specific unwind plans for trap handlers. + /// + /// \param[in] triple + /// Triple of the current target. + /// + /// \param[in] name + /// Name of the trap handler function. + /// + /// \return + /// A specific unwind plan for that trap handler, or an empty + /// shared pointer. The latter means there is no specific plan, + /// unwind as normal. + virtual lldb::UnwindPlanSP + GetTrapHandlerUnwindPlan(const llvm::Triple &triple, ConstString name) { + return {}; + } + /// Find a support executable that may not live within in the standard /// locations related to LLDB. /// @@ -865,6 +882,12 @@ public: } protected: + /// Create a list of ArchSpecs with the given OS and a architectures. The + /// vendor field is left as an "unspecified unknown". + static std::vector<ArchSpec> + CreateArchList(llvm::ArrayRef<llvm::Triple::ArchType> archs, + llvm::Triple::OSType os); + /// Private implementation of connecting to a process. If the stream is set /// we connect synchronously. lldb::ProcessSP DoConnectProcess(llvm::StringRef connect_url, @@ -920,8 +943,7 @@ protected: virtual void CalculateTrapHandlerSymbolNames() = 0; Status GetCachedExecutable(ModuleSpec &module_spec, lldb::ModuleSP &module_sp, - const FileSpecList *module_search_paths_ptr, - Platform &remote_platform); + const FileSpecList *module_search_paths_ptr); virtual Status DownloadModuleSlice(const FileSpec &src_file_spec, const uint64_t src_offset, @@ -933,6 +955,11 @@ protected: virtual const char *GetCacheHostname(); + virtual Status + ResolveRemoteExecutable(const ModuleSpec &module_spec, + lldb::ModuleSP &exe_module_sp, + const FileSpecList *module_search_paths_ptr); + private: typedef std::function<Status(const ModuleSpec &)> ModuleResolver; @@ -946,8 +973,7 @@ private: Status LoadCachedExecutable(const ModuleSpec &module_spec, lldb::ModuleSP &module_sp, - const FileSpecList *module_search_paths_ptr, - Platform &remote_platform); + const FileSpecList *module_search_paths_ptr); FileSpec GetModuleCacheRoot(); }; diff --git a/contrib/llvm-project/lldb/include/lldb/Target/Process.h b/contrib/llvm-project/lldb/include/lldb/Target/Process.h index aaa2470d2931..4627502abd25 100644 --- a/contrib/llvm-project/lldb/include/lldb/Target/Process.h +++ b/contrib/llvm-project/lldb/include/lldb/Target/Process.h @@ -99,14 +99,13 @@ public: bool GetOSPluginReportsAllThreads() const; void SetOSPluginReportsAllThreads(bool does_report); bool GetSteppingRunsAllThreads() const; + FollowForkMode GetFollowForkMode() const; protected: Process *m_process; // Can be nullptr for global ProcessProperties std::unique_ptr<ProcessExperimentalProperties> m_experimental_properties_up; }; -typedef std::shared_ptr<ProcessProperties> ProcessPropertiesSP; - // ProcessAttachInfo // // Describes any information that is required to attach to a process. @@ -239,10 +238,11 @@ public: ~ProcessModID() = default; - void BumpStopID() { - m_stop_id++; + uint32_t BumpStopID() { + const uint32_t prev_stop_id = m_stop_id++; if (!IsLastResumeForUserExpression()) m_last_natural_stop_id++; + return prev_stop_id; } void BumpMemoryID() { m_memory_id++; } @@ -500,7 +500,7 @@ public: static void SettingsTerminate(); - static const ProcessPropertiesSP &GetGlobalProperties(); + static ProcessProperties &GetGlobalProperties(); /// Find a Process plug-in that can debug \a module using the currently /// selected architecture. @@ -536,13 +536,13 @@ public: uint32_t GetAddressByteSize() const; + /// Returns the pid of the process or LLDB_INVALID_PROCESS_ID if there is + /// no known pid. + lldb::pid_t GetID() const { return m_pid; } + /// Sets the stored pid. /// /// This does not change the pid of underlying process. - lldb::pid_t GetID() const { return m_pid; } - - /// Returns the pid of the process or LLDB_INVALID_PROCESS_ID if there is - /// no known pid. void SetID(lldb::pid_t new_pid) { m_pid = new_pid; } uint32_t GetUniqueID() const { return m_process_unique_id; } @@ -611,9 +611,8 @@ public: virtual Status DoLoadCore() { Status error; - error.SetErrorStringWithFormat( - "error: %s does not support loading core files.", - GetPluginName().GetCString()); + error.SetErrorStringWithFormatv( + "error: {0} does not support loading core files.", GetPluginName()); return error; } @@ -686,6 +685,16 @@ public: "Not implemented"); } + /// Save core dump into the specified file. + /// + /// \param[in] outfile + /// Path to store core dump in. + /// + /// \return + /// true if saved successfully, false if saving the core dump + /// is not supported by the plugin, error otherwise. + virtual llvm::Expected<bool> SaveCore(llvm::StringRef outfile); + protected: virtual JITLoaderList &GetJITLoaders(); @@ -932,9 +941,9 @@ public: virtual Status DoAttachToProcessWithID(lldb::pid_t pid, const ProcessAttachInfo &attach_info) { Status error; - error.SetErrorStringWithFormat( - "error: %s does not support attaching to a process by pid", - GetPluginName().GetCString()); + error.SetErrorStringWithFormatv( + "error: {0} does not support attaching to a process by pid", + GetPluginName()); return error; } @@ -981,6 +990,15 @@ public: /// anything after a process exec's itself. virtual void DoDidExec() {} + /// Called after a reported fork. + virtual void DidFork(lldb::pid_t child_pid, lldb::tid_t child_tid) {} + + /// Called after a reported vfork. + virtual void DidVFork(lldb::pid_t child_pid, lldb::tid_t child_tid) {} + + /// Called after reported vfork completion. + virtual void DidVForkDone() {} + /// Called before launching to a process. /// /// Allow Process plug-ins to execute some code before launching a process. @@ -1008,9 +1026,8 @@ public: /// operation. virtual Status DoLaunch(Module *exe_module, ProcessLaunchInfo &launch_info) { Status error; - error.SetErrorStringWithFormat( - "error: %s does not support launching processes", - GetPluginName().GetCString()); + error.SetErrorStringWithFormatv( + "error: {0} does not support launching processes", GetPluginName()); return error; } @@ -1044,9 +1061,8 @@ public: /// \see Thread:Suspend() virtual Status DoResume() { Status error; - error.SetErrorStringWithFormat( - "error: %s does not support resuming processes", - GetPluginName().GetCString()); + error.SetErrorStringWithFormatv( + "error: {0} does not support resuming processes", GetPluginName()); return error; } @@ -1080,9 +1096,8 @@ public: /// otherwise. virtual Status DoHalt(bool &caused_stop) { Status error; - error.SetErrorStringWithFormat( - "error: %s does not support halting processes", - GetPluginName().GetCString()); + error.SetErrorStringWithFormatv( + "error: {0} does not support halting processes", GetPluginName()); return error; } @@ -1107,9 +1122,9 @@ public: /// false otherwise. virtual Status DoDetach(bool keep_stopped) { Status error; - error.SetErrorStringWithFormat( - "error: %s does not support detaching from processes", - GetPluginName().GetCString()); + error.SetErrorStringWithFormatv( + "error: {0} does not support detaching from processes", + GetPluginName()); return error; } @@ -1138,9 +1153,9 @@ public: /// Returns an error object. virtual Status DoSignal(int signal) { Status error; - error.SetErrorStringWithFormat( - "error: %s does not support sending signals to processes", - GetPluginName().GetCString()); + error.SetErrorStringWithFormatv( + "error: {0} does not support sending signals to processes", + GetPluginName()); return error; } @@ -1467,36 +1482,6 @@ public: size_t ReadMemoryFromInferior(lldb::addr_t vm_addr, void *buf, size_t size, Status &error); - /// Read a NULL terminated string from memory - /// - /// This function will read a cache page at a time until a NULL string - /// terminator is found. It will stop reading if an aligned sequence of NULL - /// termination \a type_width bytes is not found before reading \a - /// cstr_max_len bytes. The results are always guaranteed to be NULL - /// terminated, and that no more than (max_bytes - type_width) bytes will be - /// read. - /// - /// \param[in] vm_addr - /// The virtual load address to start the memory read. - /// - /// \param[in] str - /// A character buffer containing at least max_bytes. - /// - /// \param[in] max_bytes - /// The maximum number of bytes to read. - /// - /// \param[in] error - /// The error status of the read operation. - /// - /// \param[in] type_width - /// The size of the null terminator (1 to 4 bytes per - /// character). Defaults to 1. - /// - /// \return - /// The error status or the number of bytes prior to the null terminator. - size_t ReadStringFromMemory(lldb::addr_t vm_addr, char *str, size_t max_bytes, - Status &error, size_t type_width = 1); - /// Read a NULL terminated C string from memory /// /// This function will read a cache page at a time until the NULL @@ -1567,9 +1552,8 @@ public: /// The number of bytes that were actually written. virtual size_t DoWriteMemory(lldb::addr_t vm_addr, const void *buf, size_t size, Status &error) { - error.SetErrorStringWithFormat( - "error: %s does not support writing to processes", - GetPluginName().GetCString()); + error.SetErrorStringWithFormatv( + "error: {0} does not support writing to processes", GetPluginName()); return 0; } @@ -1651,9 +1635,9 @@ public: virtual lldb::addr_t DoAllocateMemory(size_t size, uint32_t permissions, Status &error) { - error.SetErrorStringWithFormat( - "error: %s does not support allocating in the debug process", - GetPluginName().GetCString()); + error.SetErrorStringWithFormatv( + "error: {0} does not support allocating in the debug process", + GetPluginName()); return LLDB_INVALID_ADDRESS; } @@ -1778,7 +1762,7 @@ public: /// /// If load_addr is within the address space the process has mapped /// range_info will be filled in with the start and end of that range as - /// well as the permissions for that range and range_info.GetMapped will + /// well as the permissions for that range and range_info. GetMapped will /// return true. /// /// If load_addr is outside any mapped region then range_info will have its @@ -1787,23 +1771,21 @@ public: /// there are no valid mapped ranges between load_addr and the end of the /// process address space. /// - /// GetMemoryRegionInfo will only return an error if it is unimplemented for - /// the current process. + /// GetMemoryRegionInfo calls DoGetMemoryRegionInfo. Override that function in + /// process subclasses. /// /// \param[in] load_addr - /// The load address to query the range_info for. + /// The load address to query the range_info for. May include non + /// address bits, these will be removed by the the ABI plugin if there is + /// one. /// /// \param[out] range_info /// An range_info value containing the details of the range. /// /// \return /// An error value. - virtual Status GetMemoryRegionInfo(lldb::addr_t load_addr, - MemoryRegionInfo &range_info) { - Status error; - error.SetErrorString("Process::GetMemoryRegionInfo() not supported"); - return error; - } + Status GetMemoryRegionInfo(lldb::addr_t load_addr, + MemoryRegionInfo &range_info); /// Obtain all the mapped memory regions within this process. /// @@ -1906,9 +1888,9 @@ public: /// \btrue if the memory was deallocated, \bfalse otherwise. virtual Status DoDeallocateMemory(lldb::addr_t ptr) { Status error; - error.SetErrorStringWithFormat( - "error: %s does not support deallocating in the debug process", - GetPluginName().GetCString()); + error.SetErrorStringWithFormatv( + "error: {0} does not support deallocating in the debug process", + GetPluginName()); return error; } @@ -2026,17 +2008,15 @@ public: virtual Status EnableBreakpointSite(BreakpointSite *bp_site) { Status error; - error.SetErrorStringWithFormat( - "error: %s does not support enabling breakpoints", - GetPluginName().GetCString()); + error.SetErrorStringWithFormatv( + "error: {0} does not support enabling breakpoints", GetPluginName()); return error; } virtual Status DisableBreakpointSite(BreakpointSite *bp_site) { Status error; - error.SetErrorStringWithFormat( - "error: %s does not support disabling breakpoints", - GetPluginName().GetCString()); + error.SetErrorStringWithFormatv( + "error: {0} does not support disabling breakpoints", GetPluginName()); return error; } @@ -2625,6 +2605,26 @@ protected: virtual size_t DoReadMemory(lldb::addr_t vm_addr, void *buf, size_t size, Status &error) = 0; + /// DoGetMemoryRegionInfo is called by GetMemoryRegionInfo after it has + /// removed non address bits from load_addr. Override this method in + /// subclasses of Process. + /// + /// See GetMemoryRegionInfo for details of the logic. + /// + /// \param[in] load_addr + /// The load address to query the range_info for. (non address bits + /// removed) + /// + /// \param[out] range_info + /// An range_info value containing the details of the range. + /// + /// \return + /// An error value. + virtual Status DoGetMemoryRegionInfo(lldb::addr_t load_addr, + MemoryRegionInfo &range_info) { + return Status("Process::DoGetMemoryRegionInfo() not supported"); + } + lldb::StateType GetPrivateState(); /// The "private" side of resuming a process. This doesn't alter the state @@ -2795,9 +2795,10 @@ protected: /// if the read failed. virtual llvm::Expected<std::vector<uint8_t>> DoReadMemoryTags(lldb::addr_t addr, size_t len, int32_t type) { - return llvm::createStringError(llvm::inconvertibleErrorCode(), - "%s does not support reading memory tags", - GetPluginName().GetCString()); + return llvm::createStringError( + llvm::inconvertibleErrorCode(), + llvm::formatv("{0} does not support reading memory tags", + GetPluginName())); } /// Does the final operation to write memory tags. E.g. sending a GDB packet. @@ -2820,8 +2821,10 @@ protected: /// Status telling you whether the write succeeded. virtual Status DoWriteMemoryTags(lldb::addr_t addr, size_t len, int32_t type, const std::vector<uint8_t> &tags) { - return Status("%s does not support writing memory tags", - GetPluginName().GetCString()); + Status status; + status.SetErrorStringWithFormatv("{0} does not support writing memory tags", + GetPluginName()); + return status; } // Type definitions diff --git a/contrib/llvm-project/lldb/include/lldb/Target/ProcessTrace.h b/contrib/llvm-project/lldb/include/lldb/Target/ProcessTrace.h index 7b9d6b13dd6f..037dea232cc0 100644 --- a/contrib/llvm-project/lldb/include/lldb/Target/ProcessTrace.h +++ b/contrib/llvm-project/lldb/include/lldb/Target/ProcessTrace.h @@ -23,9 +23,9 @@ public: static void Terminate(); - static ConstString GetPluginNameStatic(); + static llvm::StringRef GetPluginNameStatic() { return "trace"; } - static const char *GetPluginDescriptionStatic(); + static llvm::StringRef GetPluginDescriptionStatic(); ProcessTrace(lldb::TargetSP target_sp, lldb::ListenerSP listener_sp); @@ -40,9 +40,7 @@ public: SystemRuntime *GetSystemRuntime() override { return nullptr; } - ConstString GetPluginName() override; - - uint32_t GetPluginVersion() override; + llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); } Status DoDestroy() override; @@ -50,9 +48,8 @@ public: Status WillResume() override { Status error; - error.SetErrorStringWithFormat( - "error: %s does not support resuming processes", - GetPluginName().GetCString()); + error.SetErrorStringWithFormatv( + "error: {0} does not support resuming processes", GetPluginName()); return error; } diff --git a/contrib/llvm-project/lldb/include/lldb/Target/RegisterContext.h b/contrib/llvm-project/lldb/include/lldb/Target/RegisterContext.h index c5068feedd5b..392b462ecf07 100644 --- a/contrib/llvm-project/lldb/include/lldb/Target/RegisterContext.h +++ b/contrib/llvm-project/lldb/include/lldb/Target/RegisterContext.h @@ -31,10 +31,6 @@ public: virtual const RegisterInfo *GetRegisterInfoAtIndex(size_t reg) = 0; - // Detect the register size dynamically. - uint32_t UpdateDynamicRegisterSize(const lldb_private::ArchSpec &arch, - RegisterInfo *reg_info); - virtual size_t GetRegisterSetCount() = 0; virtual const RegisterSet *GetRegisterSet(size_t reg_set) = 0; diff --git a/contrib/llvm-project/lldb/include/lldb/Target/RemoteAwarePlatform.h b/contrib/llvm-project/lldb/include/lldb/Target/RemoteAwarePlatform.h index 269d15299889..f2a4ffae2aae 100644 --- a/contrib/llvm-project/lldb/include/lldb/Target/RemoteAwarePlatform.h +++ b/contrib/llvm-project/lldb/include/lldb/Target/RemoteAwarePlatform.h @@ -64,8 +64,8 @@ public: FileSpec &local_file) override; bool GetRemoteOSVersion() override; - bool GetRemoteOSBuildString(std::string &s) override; - bool GetRemoteOSKernelDescription(std::string &s) override; + llvm::Optional<std::string> GetRemoteOSBuildString() override; + llvm::Optional<std::string> GetRemoteOSKernelDescription() override; ArchSpec GetRemoteSystemArchitecture() override; Status RunShellCommand(llvm::StringRef command, const FileSpec &working_dir, diff --git a/contrib/llvm-project/lldb/include/lldb/Target/Statistics.h b/contrib/llvm-project/lldb/include/lldb/Target/Statistics.h new file mode 100644 index 000000000000..087fbee26328 --- /dev/null +++ b/contrib/llvm-project/lldb/include/lldb/Target/Statistics.h @@ -0,0 +1,142 @@ +//===-- Statistics.h --------------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_TARGET_STATISTICS_H +#define LLDB_TARGET_STATISTICS_H + +#include <chrono> +#include <string> +#include <vector> + +#include "lldb/Utility/Stream.h" +#include "lldb/lldb-forward.h" +#include "llvm/Support/JSON.h" + +namespace lldb_private { + +using StatsClock = std::chrono::high_resolution_clock; +using StatsDuration = std::chrono::duration<double>; +using StatsTimepoint = std::chrono::time_point<StatsClock>; + +/// A class that measures elapsed time in an exception safe way. +/// +/// This is a RAII class is designed to help gather timing statistics within +/// LLDB where objects have optional Duration variables that get updated with +/// elapsed times. This helps LLDB measure statistics for many things that are +/// then reported in LLDB commands. +/// +/// Objects that need to measure elapsed times should have a variable of type +/// "StatsDuration m_time_xxx;" which can then be used in the constructor of +/// this class inside a scope that wants to measure something: +/// +/// ElapsedTime elapsed(m_time_xxx); +/// // Do some work +/// +/// This class will increment the m_time_xxx variable with the elapsed time +/// when the object goes out of scope. The "m_time_xxx" variable will be +/// incremented when the class goes out of scope. This allows a variable to +/// measure something that might happen in stages at different times, like +/// resolving a breakpoint each time a new shared library is loaded. +class ElapsedTime { +public: + /// Set to the start time when the object is created. + StatsTimepoint m_start_time; + /// Elapsed time in seconds to increment when this object goes out of scope. + StatsDuration &m_elapsed_time; + +public: + ElapsedTime(StatsDuration &opt_time) : m_elapsed_time(opt_time) { + m_start_time = StatsClock::now(); + } + ~ElapsedTime() { + StatsDuration elapsed = StatsClock::now() - m_start_time; + m_elapsed_time += elapsed; + } +}; + +/// A class to count success/fail statistics. +struct StatsSuccessFail { + StatsSuccessFail(llvm::StringRef n) : name(n.str()) {} + + void NotifySuccess() { ++successes; } + void NotifyFailure() { ++failures; } + + llvm::json::Value ToJSON() const; + std::string name; + uint32_t successes = 0; + uint32_t failures = 0; +}; + +/// A class that represents statistics for a since lldb_private::Module. +struct ModuleStats { + llvm::json::Value ToJSON() const; + intptr_t identifier; + std::string path; + std::string uuid; + std::string triple; + double symtab_parse_time = 0.0; + double symtab_index_time = 0.0; + double debug_parse_time = 0.0; + double debug_index_time = 0.0; + uint64_t debug_info_size = 0; +}; + +/// A class that represents statistics for a since lldb_private::Target. +class TargetStats { +public: + llvm::json::Value ToJSON(Target &target); + + void SetLaunchOrAttachTime(); + void SetFirstPrivateStopTime(); + void SetFirstPublicStopTime(); + + StatsDuration &GetCreateTime() { return m_create_time; } + StatsSuccessFail &GetExpressionStats() { return m_expr_eval; } + StatsSuccessFail &GetFrameVariableStats() { return m_frame_var; } + +protected: + StatsDuration m_create_time{0.0}; + llvm::Optional<StatsTimepoint> m_launch_or_attach_time; + llvm::Optional<StatsTimepoint> m_first_private_stop_time; + llvm::Optional<StatsTimepoint> m_first_public_stop_time; + StatsSuccessFail m_expr_eval{"expressionEvaluation"}; + StatsSuccessFail m_frame_var{"frameVariable"}; + std::vector<intptr_t> m_module_identifiers; + void CollectStats(Target &target); +}; + +class DebuggerStats { +public: + static void SetCollectingStats(bool enable) { g_collecting_stats = enable; } + static bool GetCollectingStats() { return g_collecting_stats; } + + /// Get metrics associated with one or all targets in a debugger in JSON + /// format. + /// + /// \param debugger + /// The debugger to get the target list from if \a target is NULL. + /// + /// \param target + /// The single target to emit statistics for if non NULL, otherwise dump + /// statistics only for the specified target. + /// + /// \return + /// Returns a JSON value that contains all target metrics. + static llvm::json::Value ReportStatistics(Debugger &debugger, Target *target); + +protected: + // Collecting stats can be set to true to collect stats that are expensive + // to collect. By default all stats that are cheap to collect are enabled. + // This settings is here to maintain compatibility with "statistics enable" + // and "statistics disable". + static bool g_collecting_stats; +}; + +} // namespace lldb_private + +#endif // LLDB_TARGET_STATISTICS_H diff --git a/contrib/llvm-project/lldb/include/lldb/Target/StopInfo.h b/contrib/llvm-project/lldb/include/lldb/Target/StopInfo.h index 0e81e5160846..cdb906dcd7ed 100644 --- a/contrib/llvm-project/lldb/include/lldb/Target/StopInfo.h +++ b/contrib/llvm-project/lldb/include/lldb/Target/StopInfo.h @@ -132,6 +132,16 @@ public: static lldb::StopInfoSP CreateStopReasonProcessorTrace(Thread &thread, const char *description); + static lldb::StopInfoSP CreateStopReasonFork(Thread &thread, + lldb::pid_t child_pid, + lldb::tid_t child_tid); + + static lldb::StopInfoSP CreateStopReasonVFork(Thread &thread, + lldb::pid_t child_pid, + lldb::tid_t child_tid); + + static lldb::StopInfoSP CreateStopReasonVForkDone(Thread &thread); + static lldb::ValueObjectSP GetReturnValueObject(lldb::StopInfoSP &stop_info_sp); diff --git a/contrib/llvm-project/lldb/include/lldb/Target/Target.h b/contrib/llvm-project/lldb/include/lldb/Target/Target.h index ac8d002b09a1..7e8e1373a506 100644 --- a/contrib/llvm-project/lldb/include/lldb/Target/Target.h +++ b/contrib/llvm-project/lldb/include/lldb/Target/Target.h @@ -28,6 +28,7 @@ #include "lldb/Target/ExecutionContextScope.h" #include "lldb/Target/PathMappingList.h" #include "lldb/Target/SectionLoadHistory.h" +#include "lldb/Target/Statistics.h" #include "lldb/Target/ThreadSpec.h" #include "lldb/Utility/ArchSpec.h" #include "lldb/Utility/Broadcaster.h" @@ -122,7 +123,16 @@ public: void SetRunArguments(const Args &args); + // Get the whole environment including the platform inherited environment and + // the target specific environment, excluding the unset environment variables. Environment GetEnvironment() const; + // Get the platform inherited environment, excluding the unset environment + // variables. + Environment GetInheritedEnvironment() const; + // Get the target specific environment only, without the platform inherited + // environment. + Environment GetTargetEnvironment() const; + // Set the target specific environment. void SetEnvironment(Environment env); bool GetSkipPrologue() const; @@ -197,10 +207,6 @@ public: void SetUserSpecifiedTrapHandlerNames(const Args &args); - bool GetNonStopModeEnabled() const; - - void SetNonStopModeEnabled(bool b); - bool GetDisplayRuntimeSupportValues() const; void SetDisplayRuntimeSupportValues(bool b); @@ -557,7 +563,7 @@ public: // Settings accessors - static const lldb::TargetPropertiesSP &GetGlobalProperties(); + static TargetProperties &GetGlobalProperties(); std::recursive_mutex &GetAPIMutex(); @@ -1017,6 +1023,37 @@ public: size_t ReadCStringFromMemory(const Address &addr, char *dst, size_t dst_max_len, Status &result_error); + /// Read a NULL terminated string from memory + /// + /// This function will read a cache page at a time until a NULL string + /// terminator is found. It will stop reading if an aligned sequence of NULL + /// termination \a type_width bytes is not found before reading \a + /// cstr_max_len bytes. The results are always guaranteed to be NULL + /// terminated, and that no more than (max_bytes - type_width) bytes will be + /// read. + /// + /// \param[in] addr + /// The address to start the memory read. + /// + /// \param[in] dst + /// A character buffer containing at least max_bytes. + /// + /// \param[in] max_bytes + /// The maximum number of bytes to read. + /// + /// \param[in] error + /// The error status of the read operation. + /// + /// \param[in] type_width + /// The size of the null terminator (1 to 4 bytes per + /// character). Defaults to 1. + /// + /// \return + /// The error status or the number of bytes prior to the null terminator. + size_t ReadStringFromMemory(const Address &addr, char *dst, size_t max_bytes, + Status &error, size_t type_width, + bool force_live_memory = true); + size_t ReadScalarIntegerFromMemory(const Address &addr, uint32_t byte_size, bool is_signed, Scalar &scalar, Status &error, @@ -1446,23 +1483,22 @@ protected: // Utilities for `statistics` command. private: - std::vector<uint32_t> m_stats_storage; - bool m_collecting_stats = false; + // Target metrics storage. + TargetStats m_stats; public: - void SetCollectingStats(bool v) { m_collecting_stats = v; } - - bool GetCollectingStats() { return m_collecting_stats; } - - void IncrementStats(lldb_private::StatisticKind key) { - if (!GetCollectingStats()) - return; - lldbassert(key < lldb_private::StatisticKind::StatisticMax && - "invalid statistics!"); - m_stats_storage[key] += 1; - } + /// Get metrics associated with this target in JSON format. + /// + /// Target metrics help measure timings and information that is contained in + /// a target. These are designed to help measure performance of a debug + /// session as well as represent the current state of the target, like + /// information on the currently modules, currently set breakpoints and more. + /// + /// \return + /// Returns a JSON value that contains all target metrics. + llvm::json::Value ReportStatistics(); - std::vector<uint32_t> GetStatistics() { return m_stats_storage; } + TargetStats &GetStatistics() { return m_stats; } private: /// Construct with optional file and arch. @@ -1485,6 +1521,10 @@ private: void FinalizeFileActions(ProcessLaunchInfo &info); + /// Return a recommended size for memory reads at \a addr, optimizing for + /// cache usage. + lldb::addr_t GetReasonableReadSize(const Address &addr); + Target(const Target &) = delete; const Target &operator=(const Target &) = delete; }; diff --git a/contrib/llvm-project/lldb/include/lldb/Target/Thread.h b/contrib/llvm-project/lldb/include/lldb/Target/Thread.h index 0f6b5741573e..91feed310eb9 100644 --- a/contrib/llvm-project/lldb/include/lldb/Target/Thread.h +++ b/contrib/llvm-project/lldb/include/lldb/Target/Thread.h @@ -57,8 +57,6 @@ public: uint64_t GetMaxBacktraceDepth() const; }; -typedef std::shared_ptr<ThreadProperties> ThreadPropertiesSP; - class Thread : public std::enable_shared_from_this<Thread>, public ThreadProperties, public UserID, @@ -149,7 +147,7 @@ public: static void SettingsTerminate(); - static const ThreadPropertiesSP &GetGlobalProperties(); + static ThreadProperties &GetGlobalProperties(); lldb::ProcessSP GetProcess() const { return m_process_wp.lock(); } @@ -1017,7 +1015,8 @@ public: /// Discards the plans queued on the plan stack of the current thread. This /// is - /// arbitrated by the "Master" ThreadPlans, using the "OkayToDiscard" call. + /// arbitrated by the "Controlling" ThreadPlans, using the "OkayToDiscard" + /// call. // But if \a force is true, all thread plans are discarded. void DiscardThreadPlans(bool force); diff --git a/contrib/llvm-project/lldb/include/lldb/Target/ThreadPlan.h b/contrib/llvm-project/lldb/include/lldb/Target/ThreadPlan.h index 5e14a1fd6577..616939f89fc8 100644 --- a/contrib/llvm-project/lldb/include/lldb/Target/ThreadPlan.h +++ b/contrib/llvm-project/lldb/include/lldb/Target/ThreadPlan.h @@ -81,7 +81,7 @@ namespace lldb_private { // // Cleaning up after your plans: // -// When the plan is moved from the plan stack its WillPop method is always +// When the plan is moved from the plan stack its DidPop method is always // called, no matter why. Once it is moved off the plan stack it is done, and // won't get a chance to run again. So you should undo anything that affects // target state in this method. But be sure to leave the plan able to @@ -144,39 +144,42 @@ namespace lldb_private { // implement DoPlanExplainsStop, the result is cached in PlanExplainsStop so // the DoPlanExplainsStop itself will only get called once per stop. // -// Master plans: +// Controlling plans: // // In the normal case, when we decide to stop, we will collapse the plan // stack up to the point of the plan that understood the stop reason. // However, if a plan wishes to stay on the stack after an event it didn't -// directly handle it can designate itself a "Master" plan by responding true -// to IsMasterPlan, and then if it wants not to be discarded, it can return -// false to OkayToDiscard, and it and all its dependent plans will be +// directly handle it can designate itself a "Controlling" plan by responding +// true to IsControllingPlan, and then if it wants not to be discarded, it can +// return false to OkayToDiscard, and it and all its dependent plans will be // preserved when we resume execution. // -// The other effect of being a master plan is that when the Master plan is +// The other effect of being a controlling plan is that when the Controlling +// plan is // done , if it has set "OkayToDiscard" to false, then it will be popped & // execution will stop and return to the user. Remember that if OkayToDiscard // is false, the plan will be popped and control will be given to the next // plan above it on the stack So setting OkayToDiscard to false means the -// user will regain control when the MasterPlan is completed. +// user will regain control when the ControllingPlan is completed. // // Between these two controls this allows things like: a -// MasterPlan/DontDiscard Step Over to hit a breakpoint, stop and return +// ControllingPlan/DontDiscard Step Over to hit a breakpoint, stop and return // control to the user, but then when the user continues, the step out // succeeds. Even more tricky, when the breakpoint is hit, the user can // continue to step in/step over/etc, and finally when they continue, they // will finish up the Step Over. // -// FIXME: MasterPlan & OkayToDiscard aren't really orthogonal. MasterPlan +// FIXME: ControllingPlan & OkayToDiscard aren't really orthogonal. +// ControllingPlan // designation means that this plan controls it's fate and the fate of plans -// below it. OkayToDiscard tells whether the MasterPlan wants to stay on the -// stack. I originally thought "MasterPlan-ness" would need to be a fixed +// below it. OkayToDiscard tells whether the ControllingPlan wants to stay on +// the stack. I originally thought "ControllingPlan-ness" would need to be a +// fixed // characteristic of a ThreadPlan, in which case you needed the extra control. // But that doesn't seem to be true. So we should be able to convert to only -// MasterPlan status to mean the current "MasterPlan/DontDiscard". Then no -// plans would be MasterPlans by default, and you would set the ones you -// wanted to be "user level" in this way. +// ControllingPlan status to mean the current "ControllingPlan/DontDiscard". +// Then no plans would be ControllingPlans by default, and you would set the +// ones you wanted to be "user level" in this way. // // // Actually Stopping: @@ -224,9 +227,11 @@ namespace lldb_private { // // Cleaning up the plan stack: // -// One of the complications of MasterPlans is that you may get past the limits +// One of the complications of ControllingPlans is that you may get past the +// limits // of a plan without triggering it to clean itself up. For instance, if you -// are doing a MasterPlan StepOver, and hit a breakpoint in a called function, +// are doing a ControllingPlan StepOver, and hit a breakpoint in a called +// function, // then step over enough times to step out of the initial StepOver range, each // of the step overs will explain the stop & take themselves off the stack, // but control would never be returned to the original StepOver. Eventually, @@ -386,11 +391,11 @@ public: virtual bool WillStop() = 0; - bool IsMasterPlan() { return m_is_master_plan; } + bool IsControllingPlan() { return m_is_controlling_plan; } - bool SetIsMasterPlan(bool value) { - bool old_value = m_is_master_plan; - m_is_master_plan = value; + bool SetIsControllingPlan(bool value) { + bool old_value = m_is_controlling_plan; + m_is_controlling_plan = value; return old_value; } @@ -413,7 +418,7 @@ public: virtual void DidPush(); - virtual void WillPop(); + virtual void DidPop(); ThreadPlanKind GetKind() const { return m_kind; } @@ -490,12 +495,12 @@ protected: virtual bool DoPlanExplainsStop(Event *event_ptr) = 0; // This pushes a plan onto the plan stack of the current plan's thread. - // Also sets the plans to private and not master plans. A plan pushed by + // Also sets the plans to private and not controlling plans. A plan pushed by // another thread plan is never either of the above. void PushPlan(lldb::ThreadPlanSP &thread_plan_sp) { GetThread().PushPlan(thread_plan_sp); thread_plan_sp->SetPrivate(true); - thread_plan_sp->SetIsMasterPlan(false); + thread_plan_sp->SetIsControllingPlan(false); } // This gets the previous plan to the current plan (for forwarding requests). @@ -546,7 +551,7 @@ private: bool m_plan_complete; bool m_plan_private; bool m_okay_to_discard; - bool m_is_master_plan; + bool m_is_controlling_plan; bool m_plan_succeeded; lldb::ThreadPlanTracerSP m_tracer_sp; diff --git a/contrib/llvm-project/lldb/include/lldb/Target/ThreadPlanCallFunction.h b/contrib/llvm-project/lldb/include/lldb/Target/ThreadPlanCallFunction.h index 24c5736f44c3..cb6e7caebb4a 100644 --- a/contrib/llvm-project/lldb/include/lldb/Target/ThreadPlanCallFunction.h +++ b/contrib/llvm-project/lldb/include/lldb/Target/ThreadPlanCallFunction.h @@ -68,10 +68,10 @@ public: // been cleaned up. lldb::addr_t GetFunctionStackPointer() { return m_function_sp; } - // Classes that derive from FunctionCaller, and implement their own WillPop + // Classes that derive from FunctionCaller, and implement their own DidPop // methods should call this so that the thread state gets restored if the // plan gets discarded. - void WillPop() override; + void DidPop() override; // If the thread plan stops mid-course, this will be the stop reason that // interrupted us. Once DoTakedown is called, this will be the real stop diff --git a/contrib/llvm-project/lldb/include/lldb/Target/ThreadPlanCallUserExpression.h b/contrib/llvm-project/lldb/include/lldb/Target/ThreadPlanCallUserExpression.h index adaea6c7056f..11e126a2da9c 100644 --- a/contrib/llvm-project/lldb/include/lldb/Target/ThreadPlanCallUserExpression.h +++ b/contrib/llvm-project/lldb/include/lldb/Target/ThreadPlanCallUserExpression.h @@ -32,7 +32,7 @@ public: void DidPush() override; - void WillPop() override; + void DidPop() override; lldb::StopInfoSP GetRealStopInfo() override; diff --git a/contrib/llvm-project/lldb/include/lldb/Target/ThreadPlanStack.h b/contrib/llvm-project/lldb/include/lldb/Target/ThreadPlanStack.h index e0f76f8e1df5..90f1ea3a284b 100644 --- a/contrib/llvm-project/lldb/include/lldb/Target/ThreadPlanStack.h +++ b/contrib/llvm-project/lldb/include/lldb/Target/ThreadPlanStack.h @@ -60,7 +60,7 @@ public: void DiscardAllPlans(); - void DiscardConsultingMasterPlans(); + void DiscardConsultingControllingPlans(); lldb::ThreadPlanSP GetCurrentPlan() const; diff --git a/contrib/llvm-project/lldb/include/lldb/Target/ThreadPlanStepOverBreakpoint.h b/contrib/llvm-project/lldb/include/lldb/Target/ThreadPlanStepOverBreakpoint.h index 86f7798487c3..1f3aff45c49a 100644 --- a/contrib/llvm-project/lldb/include/lldb/Target/ThreadPlanStepOverBreakpoint.h +++ b/contrib/llvm-project/lldb/include/lldb/Target/ThreadPlanStepOverBreakpoint.h @@ -26,7 +26,7 @@ public: bool StopOthers() override; lldb::StateType GetPlanRunState() override; bool WillStop() override; - void WillPop() override; + void DidPop() override; bool MischiefManaged() override; void ThreadDestroyed() override; void SetAutoContinue(bool do_it); diff --git a/contrib/llvm-project/lldb/include/lldb/Target/Trace.h b/contrib/llvm-project/lldb/include/lldb/Target/Trace.h index f5654988b201..643b761cdb89 100644 --- a/contrib/llvm-project/lldb/include/lldb/Target/Trace.h +++ b/contrib/llvm-project/lldb/include/lldb/Target/Trace.h @@ -20,6 +20,7 @@ #include "lldb/Utility/TraceGDBRemotePackets.h" #include "lldb/Utility/UnimplementedError.h" #include "lldb/lldb-private.h" +#include "lldb/lldb-types.h" namespace lldb_private { @@ -55,6 +56,22 @@ public: /// A stream object to dump the information to. virtual void Dump(Stream *s) const = 0; + /// Save the trace of a live process to the specified directory, which + /// will be created if needed. + /// This will also create a a file \a <directory>/trace.json with the main + /// properties of the trace session, along with others files which contain + /// the actual trace data. The trace.json file can be used later as input + /// for the "trace load" command to load the trace in LLDB. + /// The process being trace is not a live process, return an error. + /// + /// \param[in] directory + /// The directory where the trace files will be saved. + /// + /// \return + /// \a llvm::success if the operation was successful, or an \a llvm::Error + /// otherwise. + virtual llvm::Error SaveLiveTraceToDisk(FileSpec directory) = 0; + /// Find a trace plug-in using JSON data. /// /// When loading trace data from disk, the information for the trace data @@ -156,12 +173,12 @@ public: /// Check if a thread is currently traced by this object. /// - /// \param[in] thread - /// The thread in question. + /// \param[in] tid + /// The id of the thread in question. /// /// \return /// \b true if the thread is traced by this instance, \b false otherwise. - virtual bool IsTraced(const Thread &thread) = 0; + virtual bool IsTraced(lldb::tid_t tid) = 0; /// \return /// A description of the parameters to use for the \a Trace::Start method. diff --git a/contrib/llvm-project/lldb/include/lldb/Target/TraceExporter.h b/contrib/llvm-project/lldb/include/lldb/Target/TraceExporter.h index 6560b39fd42e..d5a06c499a6e 100644 --- a/contrib/llvm-project/lldb/include/lldb/Target/TraceExporter.h +++ b/contrib/llvm-project/lldb/include/lldb/Target/TraceExporter.h @@ -10,6 +10,8 @@ #define LLDB_TARGET_TRACE_EXPORTER_H #include "lldb/Core/PluginInterface.h" +#include "lldb/lldb-forward.h" +#include "llvm/Support/Error.h" namespace lldb_private { diff --git a/contrib/llvm-project/lldb/include/lldb/Target/UnixSignals.h b/contrib/llvm-project/lldb/include/lldb/Target/UnixSignals.h index 6fecdda12def..1c91c9fdd489 100644 --- a/contrib/llvm-project/lldb/include/lldb/Target/UnixSignals.h +++ b/contrib/llvm-project/lldb/include/lldb/Target/UnixSignals.h @@ -16,6 +16,7 @@ #include "lldb/Utility/ConstString.h" #include "lldb/lldb-private.h" #include "llvm/ADT/Optional.h" +#include "llvm/Support/JSON.h" namespace lldb_private { @@ -80,6 +81,18 @@ public: void RemoveSignal(int signo); + /// Track how many times signals are hit as stop reasons. + void IncrementSignalHitCount(int signo); + + /// Get the hit count statistics for signals. + /// + /// Gettings statistics on the hit counts of signals can help explain why some + /// debug sessions are slow since each stop takes a few hundred ms and some + /// software use signals a lot and can cause slow debugging performance if + /// they are used too often. Even if a signal is not stopped at, it will auto + /// continue the process and a delay will happen. + llvm::json::Value GetHitCountStatistics() const; + // Returns a current version of the data stored in this class. Version gets // incremented each time Set... method is called. uint64_t GetVersion() const; @@ -99,6 +112,7 @@ protected: ConstString m_name; ConstString m_alias; std::string m_description; + uint32_t m_hit_count = 0; bool m_suppress : 1, m_stop : 1, m_notify : 1; Signal(const char *name, bool default_suppress, bool default_stop, diff --git a/contrib/llvm-project/lldb/include/lldb/Utility/ConstString.h b/contrib/llvm-project/lldb/include/lldb/Utility/ConstString.h index 52d3556418f6..2756f1fd7203 100644 --- a/contrib/llvm-project/lldb/include/lldb/Utility/ConstString.h +++ b/contrib/llvm-project/lldb/include/lldb/Utility/ConstString.h @@ -409,7 +409,7 @@ public: static size_t StaticMemorySize(); protected: - template <typename T> friend struct ::llvm::DenseMapInfo; + template <typename T, typename Enable> friend struct ::llvm::DenseMapInfo; /// Only used by DenseMapInfo. static ConstString FromStringPoolPointer(const char *ptr) { ConstString s; diff --git a/contrib/llvm-project/lldb/include/lldb/Utility/DataExtractor.h b/contrib/llvm-project/lldb/include/lldb/Utility/DataExtractor.h index 0923e5280cba..dbf0bce8c8d0 100644 --- a/contrib/llvm-project/lldb/include/lldb/Utility/DataExtractor.h +++ b/contrib/llvm-project/lldb/include/lldb/Utility/DataExtractor.h @@ -134,7 +134,12 @@ public: DataExtractor(const DataExtractor &data, lldb::offset_t offset, lldb::offset_t length, uint32_t target_byte_size = 1); - DataExtractor(const DataExtractor &rhs); + /// Copy constructor. + /// + /// The copy constructor is explicit as otherwise it is easy to make + /// unintended modification of a local copy instead of a caller's instance. + /// Also a needless copy of the \a m_data_sp shared pointer is/ expensive. + explicit DataExtractor(const DataExtractor &rhs); /// Assignment operator. /// @@ -149,6 +154,12 @@ public: /// A const reference to this object. const DataExtractor &operator=(const DataExtractor &rhs); + /// Move constructor and move assignment operators to complete the rule of 5. + /// + /// They would get deleted as we already defined those of rule of 3. + DataExtractor(DataExtractor &&rhs) = default; + DataExtractor &operator=(DataExtractor &&rhs) = default; + /// Destructor /// /// If this object contains a valid shared data reference, the reference @@ -1005,7 +1016,8 @@ protected: uint32_t m_addr_size; ///< The address size to use when extracting addresses. /// The shared pointer to data that can be shared among multiple instances lldb::DataBufferSP m_data_sp; - const uint32_t m_target_byte_size = 1; + /// Making it const would require implementation of move assignment operator. + uint32_t m_target_byte_size = 1; }; } // namespace lldb_private diff --git a/contrib/llvm-project/lldb/include/lldb/Utility/Environment.h b/contrib/llvm-project/lldb/include/lldb/Utility/Environment.h index e2af2eb2463d..24cbee246f83 100644 --- a/contrib/llvm-project/lldb/include/lldb/Utility/Environment.h +++ b/contrib/llvm-project/lldb/include/lldb/Utility/Environment.h @@ -73,7 +73,7 @@ public: return insert(std::make_pair(Split.first, std::string(Split.second))); } - void insert(const_iterator first, const_iterator last); + void insert(iterator first, iterator last); Envp getEnvp() const { return Envp(*this); } diff --git a/contrib/llvm-project/lldb/include/lldb/Utility/FileSpec.h b/contrib/llvm-project/lldb/include/lldb/Utility/FileSpec.h index 0f4e6505e433..305cd04f95c0 100644 --- a/contrib/llvm-project/lldb/include/lldb/Utility/FileSpec.h +++ b/contrib/llvm-project/lldb/include/lldb/Utility/FileSpec.h @@ -202,7 +202,7 @@ public: /// \return /// \b true if the file path is case sensitive (POSIX), false /// if case insensitive (Windows). - bool IsCaseSensitive() const { return m_style != Style::windows; } + bool IsCaseSensitive() const { return is_style_posix(m_style); } /// Dump this object to a Stream. /// diff --git a/contrib/llvm-project/lldb/include/lldb/Utility/ReproducerInstrumentation.h b/contrib/llvm-project/lldb/include/lldb/Utility/ReproducerInstrumentation.h index 2b2d273a17a8..6c5d27879d36 100644 --- a/contrib/llvm-project/lldb/include/lldb/Utility/ReproducerInstrumentation.h +++ b/contrib/llvm-project/lldb/include/lldb/Utility/ReproducerInstrumentation.h @@ -868,17 +868,14 @@ public: /// Mark the current thread as a private thread and pretend that everything /// on this thread is behind happening behind the API boundary. - static void PrivateThread() { g_global_boundary = true; } + static void PrivateThread(); private: static unsigned GetNextSequenceNumber() { return g_sequence++; } unsigned GetSequenceNumber() const; template <typename T> friend struct replay; - void UpdateBoundary() { - if (m_local_boundary) - g_global_boundary = false; - } + void UpdateBoundary(); #ifdef LLDB_REPRO_INSTR_TRACE void Log(unsigned id) { @@ -902,9 +899,6 @@ private: /// The sequence number for this pair of function and result. unsigned m_sequence; - /// Whether we're currently across the API boundary. - static thread_local bool g_global_boundary; - /// Global mutex to protect concurrent access. static std::mutex g_mutex; diff --git a/contrib/llvm-project/lldb/include/lldb/Utility/Status.h b/contrib/llvm-project/lldb/include/lldb/Utility/Status.h index 61d663bdccba..bee2b57b6ea9 100644 --- a/contrib/llvm-project/lldb/include/lldb/Utility/Status.h +++ b/contrib/llvm-project/lldb/include/lldb/Utility/Status.h @@ -184,16 +184,6 @@ public: /// success (non-erro), \b false otherwise. bool Success() const; - /// Test for a failure due to a generic interrupt. - /// - /// Returns true if the error code in this object was caused by an - /// interrupt. At present only supports Posix EINTR. - /// - /// \return - /// \b true if this object contains an value that describes - /// failure due to interrupt, \b false otherwise. - bool WasInterrupted() const; - protected: /// Member variables ValueType m_code = 0; ///< Status code as an integer value. diff --git a/contrib/llvm-project/lldb/include/lldb/Utility/StringExtractorGDBRemote.h b/contrib/llvm-project/lldb/include/lldb/Utility/StringExtractorGDBRemote.h index c67c05bdf182..1712c113d396 100644 --- a/contrib/llvm-project/lldb/include/lldb/Utility/StringExtractorGDBRemote.h +++ b/contrib/llvm-project/lldb/include/lldb/Utility/StringExtractorGDBRemote.h @@ -88,6 +88,7 @@ public: eServerPacketType_vFile_mode, eServerPacketType_vFile_exists, eServerPacketType_vFile_md5, + eServerPacketType_vFile_fstat, eServerPacketType_vFile_stat, eServerPacketType_vFile_symlink, eServerPacketType_vFile_unlink, @@ -135,6 +136,7 @@ public: eServerPacketType_vAttachName, eServerPacketType_vCont, eServerPacketType_vCont_actions, // vCont? + eServerPacketType_vRun, eServerPacketType_stop_reason, // '?' @@ -170,6 +172,8 @@ public: eServerPacketType_qMemTags, // read memory tags eServerPacketType_QMemTags, // write memory tags + + eServerPacketType_qLLDBSaveCore, }; ServerPacketType GetServerPacketType() const; diff --git a/contrib/llvm-project/lldb/include/lldb/Utility/StructuredData.h b/contrib/llvm-project/lldb/include/lldb/Utility/StructuredData.h index 4d03af18e527..c1d136db1c2e 100644 --- a/contrib/llvm-project/lldb/include/lldb/Utility/StructuredData.h +++ b/contrib/llvm-project/lldb/include/lldb/Utility/StructuredData.h @@ -353,6 +353,17 @@ public: public: Dictionary() : Object(lldb::eStructuredDataTypeDictionary), m_dict() {} + Dictionary(ObjectSP obj_sp) + : Object(lldb::eStructuredDataTypeDictionary), m_dict() { + if (!obj_sp || obj_sp->GetType() != lldb::eStructuredDataTypeDictionary) { + SetType(lldb::eStructuredDataTypeInvalid); + return; + } + + Dictionary *dict = obj_sp->GetAsDictionary(); + m_dict = dict->m_dict; + } + ~Dictionary() override = default; size_t GetSize() const { return m_dict.size(); } diff --git a/contrib/llvm-project/lldb/include/lldb/Utility/Timer.h b/contrib/llvm-project/lldb/include/lldb/Utility/Timer.h index c70c18049426..201378bbeb2c 100644 --- a/contrib/llvm-project/lldb/include/lldb/Utility/Timer.h +++ b/contrib/llvm-project/lldb/include/lldb/Utility/Timer.h @@ -9,16 +9,11 @@ #ifndef LLDB_UTILITY_TIMER_H #define LLDB_UTILITY_TIMER_H -#include "llvm/ADT/ScopeExit.h" +#include "lldb/lldb-defines.h" #include "llvm/Support/Chrono.h" -#include "llvm/Support/Signposts.h" #include <atomic> #include <cstdint> -namespace llvm { - class SignpostEmitter; -} - namespace lldb_private { class Stream; @@ -81,28 +76,15 @@ private: const Timer &operator=(const Timer &) = delete; }; -llvm::SignpostEmitter &GetSignposts(); - } // namespace lldb_private // Use a format string because LLVM_PRETTY_FUNCTION might not be a string // literal. #define LLDB_SCOPED_TIMER() \ static ::lldb_private::Timer::Category _cat(LLVM_PRETTY_FUNCTION); \ - ::lldb_private::Timer _scoped_timer(_cat, "%s", LLVM_PRETTY_FUNCTION); \ - SIGNPOST_EMITTER_START_INTERVAL(::lldb_private::GetSignposts(), \ - &_scoped_timer, "%s", LLVM_PRETTY_FUNCTION); \ - auto _scoped_signpost = llvm::make_scope_exit([&_scoped_timer]() { \ - ::lldb_private::GetSignposts().endInterval(&_scoped_timer); \ - }) - -#define LLDB_SCOPED_TIMERF(FMT, ...) \ + ::lldb_private::Timer _scoped_timer(_cat, "%s", LLVM_PRETTY_FUNCTION) +#define LLDB_SCOPED_TIMERF(...) \ static ::lldb_private::Timer::Category _cat(LLVM_PRETTY_FUNCTION); \ - ::lldb_private::Timer _scoped_timer(_cat, FMT, __VA_ARGS__); \ - SIGNPOST_EMITTER_START_INTERVAL(::lldb_private::GetSignposts(), \ - &_scoped_timer, FMT, __VA_ARGS__); \ - auto _scoped_signpost = llvm::make_scope_exit([&_scoped_timer]() { \ - ::lldb_private::GetSignposts().endInterval(&_scoped_timer); \ - }) + ::lldb_private::Timer _scoped_timer(_cat, __VA_ARGS__) #endif // LLDB_UTILITY_TIMER_H diff --git a/contrib/llvm-project/lldb/include/lldb/Utility/UriParser.h b/contrib/llvm-project/lldb/include/lldb/Utility/UriParser.h index 6a64c3d747b5..3c0f8d2273d0 100644 --- a/contrib/llvm-project/lldb/include/lldb/Utility/UriParser.h +++ b/contrib/llvm-project/lldb/include/lldb/Utility/UriParser.h @@ -9,23 +9,27 @@ #ifndef LLDB_UTILITY_URIPARSER_H #define LLDB_UTILITY_URIPARSER_H +#include "llvm/ADT/Optional.h" #include "llvm/ADT/StringRef.h" namespace lldb_private { -class UriParser { -public: - // Parses - // RETURN VALUE - // if url is valid, function returns true and - // scheme/hostname/port/path are set to the parsed values - // port it set to -1 if it is not included in the URL - // - // if the url is invalid, function returns false and - // output parameters remain unchanged - static bool Parse(llvm::StringRef uri, llvm::StringRef &scheme, - llvm::StringRef &hostname, int &port, - llvm::StringRef &path); + +struct URI { + llvm::StringRef scheme; + llvm::StringRef hostname; + llvm::Optional<uint16_t> port; + llvm::StringRef path; + + bool operator==(const URI &R) const { + return port == R.port && scheme == R.scheme && hostname == R.hostname && + path == R.path; + } + + static llvm::Optional<URI> Parse(llvm::StringRef uri); }; -} + +llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const URI &U); + +} // namespace lldb_private #endif // LLDB_UTILITY_URIPARSER_H diff --git a/contrib/llvm-project/lldb/include/lldb/lldb-enumerations.h b/contrib/llvm-project/lldb/include/lldb/lldb-enumerations.h index 0d68833c12f5..a586b8423331 100644 --- a/contrib/llvm-project/lldb/include/lldb/lldb-enumerations.h +++ b/contrib/llvm-project/lldb/include/lldb/lldb-enumerations.h @@ -1137,6 +1137,7 @@ enum SaveCoreStyle { eSaveCoreUnspecified = 0, eSaveCoreFull = 1, eSaveCoreDirtyOnly = 2, + eSaveCoreStackOnly = 3, }; } // namespace lldb diff --git a/contrib/llvm-project/lldb/include/lldb/lldb-forward.h b/contrib/llvm-project/lldb/include/lldb/lldb-forward.h index ad5298151e4a..482da17bfacb 100644 --- a/contrib/llvm-project/lldb/include/lldb/lldb-forward.h +++ b/contrib/llvm-project/lldb/include/lldb/lldb-forward.h @@ -175,6 +175,7 @@ class Scalar; class ScriptInterpreter; class ScriptInterpreterLocker; class ScriptedProcessInterface; +class ScriptedThreadInterface; class ScriptedSyntheticChildren; class SearchFilter; class Section; @@ -290,7 +291,6 @@ typedef std::shared_ptr<lldb_private::Block> BlockSP; typedef std::shared_ptr<lldb_private::Breakpoint> BreakpointSP; typedef std::weak_ptr<lldb_private::Breakpoint> BreakpointWP; typedef std::shared_ptr<lldb_private::BreakpointSite> BreakpointSiteSP; -typedef std::weak_ptr<lldb_private::BreakpointSite> BreakpointSiteWP; typedef std::shared_ptr<lldb_private::BreakpointLocation> BreakpointLocationSP; typedef std::weak_ptr<lldb_private::BreakpointLocation> BreakpointLocationWP; typedef std::shared_ptr<lldb_private::BreakpointPrecondition> @@ -301,7 +301,6 @@ typedef std::shared_ptr<lldb_private::BroadcasterManager> BroadcasterManagerSP; typedef std::weak_ptr<lldb_private::BroadcasterManager> BroadcasterManagerWP; typedef std::shared_ptr<lldb_private::UserExpression> UserExpressionSP; typedef std::shared_ptr<lldb_private::CommandObject> CommandObjectSP; -typedef std::shared_ptr<lldb_private::Communication> CommunicationSP; typedef std::shared_ptr<lldb_private::Connection> ConnectionSP; typedef std::shared_ptr<lldb_private::CompileUnit> CompUnitSP; typedef std::shared_ptr<lldb_private::DataBuffer> DataBufferSP; @@ -311,7 +310,6 @@ typedef std::weak_ptr<lldb_private::Debugger> DebuggerWP; typedef std::shared_ptr<lldb_private::Disassembler> DisassemblerSP; typedef std::unique_ptr<lldb_private::DynamicCheckerFunctions> DynamicCheckerFunctionsUP; -typedef std::shared_ptr<lldb_private::DynamicLoader> DynamicLoaderSP; typedef std::unique_ptr<lldb_private::DynamicLoader> DynamicLoaderUP; typedef std::shared_ptr<lldb_private::Event> EventSP; typedef std::shared_ptr<lldb_private::EventData> EventDataSP; @@ -323,7 +321,6 @@ typedef std::shared_ptr<lldb_private::ExpressionVariable> ExpressionVariableSP; typedef std::unique_ptr<lldb_private::File> FileUP; typedef std::shared_ptr<lldb_private::File> FileSP; typedef std::shared_ptr<lldb_private::Function> FunctionSP; -typedef std::shared_ptr<lldb_private::FunctionCaller> FunctionCallerSP; typedef std::shared_ptr<lldb_private::FuncUnwinders> FuncUnwindersSP; typedef std::shared_ptr<lldb_private::InlineFunctionInfo> InlineFunctionInfoSP; typedef std::shared_ptr<lldb_private::Instruction> InstructionSP; @@ -335,9 +332,7 @@ typedef std::shared_ptr<lldb_private::IRExecutionUnit> IRExecutionUnitSP; typedef std::shared_ptr<lldb_private::JITLoader> JITLoaderSP; typedef std::unique_ptr<lldb_private::JITLoaderList> JITLoaderListUP; typedef std::shared_ptr<lldb_private::LanguageRuntime> LanguageRuntimeSP; -typedef std::shared_ptr<lldb_private::SystemRuntime> SystemRuntimeSP; typedef std::unique_ptr<lldb_private::SystemRuntime> SystemRuntimeUP; -typedef std::shared_ptr<lldb_private::LineTable> LineTableSP; typedef std::shared_ptr<lldb_private::Listener> ListenerSP; typedef std::weak_ptr<lldb_private::Listener> ListenerWP; typedef std::shared_ptr<lldb_private::MemoryHistory> MemoryHistorySP; @@ -346,7 +341,6 @@ typedef std::shared_ptr<lldb_private::MemoryRegionInfo> MemoryRegionInfoSP; typedef std::shared_ptr<lldb_private::Module> ModuleSP; typedef std::weak_ptr<lldb_private::Module> ModuleWP; typedef std::shared_ptr<lldb_private::ObjectFile> ObjectFileSP; -typedef std::weak_ptr<lldb_private::ObjectFile> ObjectFileWP; typedef std::shared_ptr<lldb_private::ObjectFileJITDelegate> ObjectFileJITDelegateSP; typedef std::weak_ptr<lldb_private::ObjectFileJITDelegate> @@ -354,32 +348,12 @@ typedef std::weak_ptr<lldb_private::ObjectFileJITDelegate> typedef std::unique_ptr<lldb_private::OperatingSystem> OperatingSystemUP; typedef std::shared_ptr<lldb_private::OptionValue> OptionValueSP; typedef std::weak_ptr<lldb_private::OptionValue> OptionValueWP; -typedef std::shared_ptr<lldb_private::OptionValueArch> OptionValueArchSP; -typedef std::shared_ptr<lldb_private::OptionValueArgs> OptionValueArgsSP; -typedef std::shared_ptr<lldb_private::OptionValueArray> OptionValueArraySP; -typedef std::shared_ptr<lldb_private::OptionValueBoolean> OptionValueBooleanSP; -typedef std::shared_ptr<lldb_private::OptionValueDictionary> - OptionValueDictionarySP; -typedef std::shared_ptr<lldb_private::OptionValueFileSpec> - OptionValueFileSpecSP; -typedef std::shared_ptr<lldb_private::OptionValueFileSpecList> - OptionValueFileSpecListSP; -typedef std::shared_ptr<lldb_private::OptionValueFormat> OptionValueFormatSP; -typedef std::shared_ptr<lldb_private::OptionValuePathMappings> - OptionValuePathMappingsSP; typedef std::shared_ptr<lldb_private::OptionValueProperties> OptionValuePropertiesSP; -typedef std::shared_ptr<lldb_private::OptionValueRegex> OptionValueRegexSP; -typedef std::shared_ptr<lldb_private::OptionValueSInt64> OptionValueSInt64SP; -typedef std::shared_ptr<lldb_private::OptionValueString> OptionValueStringSP; -typedef std::shared_ptr<lldb_private::OptionValueUInt64> OptionValueUInt64SP; -typedef std::shared_ptr<lldb_private::OptionValueUUID> OptionValueUUIDSP; typedef std::shared_ptr<lldb_private::Platform> PlatformSP; typedef std::shared_ptr<lldb_private::Process> ProcessSP; typedef std::shared_ptr<lldb_private::ProcessAttachInfo> ProcessAttachInfoSP; -typedef std::shared_ptr<lldb_private::ProcessLaunchInfo> ProcessLaunchInfoSP; typedef std::weak_ptr<lldb_private::Process> ProcessWP; -typedef std::shared_ptr<lldb_private::Property> PropertySP; typedef std::shared_ptr<lldb_private::RegisterCheckpoint> RegisterCheckpointSP; typedef std::shared_ptr<lldb_private::RegisterContext> RegisterContextSP; typedef std::shared_ptr<lldb_private::RegularExpression> RegularExpressionSP; @@ -392,18 +366,17 @@ typedef std::shared_ptr<lldb_private::RecognizedStackFrame> typedef std::shared_ptr<lldb_private::ScriptSummaryFormat> ScriptSummaryFormatSP; typedef std::shared_ptr<lldb_private::ScriptInterpreter> ScriptInterpreterSP; -typedef std::unique_ptr<lldb_private::ScriptInterpreter> ScriptInterpreterUP; typedef std::unique_ptr<lldb_private::ScriptedProcessInterface> ScriptedProcessInterfaceUP; +typedef std::shared_ptr<lldb_private::ScriptedThreadInterface> + ScriptedThreadInterfaceSP; typedef std::shared_ptr<lldb_private::Section> SectionSP; typedef std::unique_ptr<lldb_private::SectionList> SectionListUP; typedef std::weak_ptr<lldb_private::Section> SectionWP; typedef std::shared_ptr<lldb_private::SectionLoadList> SectionLoadListSP; typedef std::shared_ptr<lldb_private::SearchFilter> SearchFilterSP; -typedef std::shared_ptr<lldb_private::Settings> SettingsSP; typedef std::unique_ptr<lldb_private::SourceManager> SourceManagerUP; typedef std::shared_ptr<lldb_private::StackFrame> StackFrameSP; -typedef std::unique_ptr<lldb_private::StackFrame> StackFrameUP; typedef std::weak_ptr<lldb_private::StackFrame> StackFrameWP; typedef std::shared_ptr<lldb_private::StackFrameList> StackFrameListSP; typedef std::shared_ptr<lldb_private::StackFrameRecognizer> @@ -412,7 +385,6 @@ typedef std::unique_ptr<lldb_private::StackFrameRecognizerManager> StackFrameRecognizerManagerUP; typedef std::shared_ptr<lldb_private::StopInfo> StopInfoSP; typedef std::shared_ptr<lldb_private::Stream> StreamSP; -typedef std::weak_ptr<lldb_private::Stream> StreamWP; typedef std::shared_ptr<lldb_private::StreamFile> StreamFileSP; typedef std::shared_ptr<lldb_private::StringSummaryFormat> StringTypeSummaryImplSP; @@ -421,9 +393,7 @@ typedef std::shared_ptr<lldb_private::StructuredDataPlugin> StructuredDataPluginSP; typedef std::weak_ptr<lldb_private::StructuredDataPlugin> StructuredDataPluginWP; -typedef std::shared_ptr<lldb_private::SymbolFile> SymbolFileSP; typedef std::shared_ptr<lldb_private::SymbolFileType> SymbolFileTypeSP; -typedef std::weak_ptr<lldb_private::SymbolFileType> SymbolFileTypeWP; typedef std::shared_ptr<lldb_private::SymbolContextSpecifier> SymbolContextSpecifierSP; typedef std::unique_ptr<lldb_private::SymbolVendor> SymbolVendorUP; @@ -432,7 +402,6 @@ typedef std::shared_ptr<lldb_private::SyntheticChildrenFrontEnd> SyntheticChildrenFrontEndSP; typedef std::shared_ptr<lldb_private::Target> TargetSP; typedef std::weak_ptr<lldb_private::Target> TargetWP; -typedef std::shared_ptr<lldb_private::TargetProperties> TargetPropertiesSP; typedef std::shared_ptr<lldb_private::Thread> ThreadSP; typedef std::weak_ptr<lldb_private::Thread> ThreadWP; typedef std::shared_ptr<lldb_private::ThreadCollection> ThreadCollectionSP; @@ -464,10 +433,8 @@ typedef std::shared_ptr<lldb_private::UnixSignals> UnixSignalsSP; typedef std::weak_ptr<lldb_private::UnixSignals> UnixSignalsWP; typedef std::shared_ptr<lldb_private::UnwindAssembly> UnwindAssemblySP; typedef std::shared_ptr<lldb_private::UnwindPlan> UnwindPlanSP; -typedef std::shared_ptr<lldb_private::UtilityFunction> UtilityFunctionSP; typedef std::shared_ptr<lldb_private::ValueObject> ValueObjectSP; typedef std::shared_ptr<lldb_private::Value> ValueSP; -typedef std::shared_ptr<lldb_private::ValueList> ValueListSP; typedef std::shared_ptr<lldb_private::Variable> VariableSP; typedef std::shared_ptr<lldb_private::VariableList> VariableListSP; typedef std::shared_ptr<lldb_private::ValueObjectList> ValueObjectListSP; diff --git a/contrib/llvm-project/lldb/include/lldb/lldb-private-enumerations.h b/contrib/llvm-project/lldb/include/lldb/lldb-private-enumerations.h index 7009d1b4fba7..9bbb889359b1 100644 --- a/contrib/llvm-project/lldb/include/lldb/lldb-private-enumerations.h +++ b/contrib/llvm-project/lldb/include/lldb/lldb-private-enumerations.h @@ -172,6 +172,12 @@ enum MemoryModuleLoadLevel { eMemoryModuleLoadLevelComplete, // Load sections and all symbols }; +// Behavior on fork/vfork +enum FollowForkMode { + eFollowParent, // Follow parent process + eFollowChild, // Follow child process +}; + // Result enums for when reading multiple lines from IOHandlers enum class LineStatus { Success, // The line that was just edited if good and should be added to the diff --git a/contrib/llvm-project/lldb/include/lldb/lldb-private-types.h b/contrib/llvm-project/lldb/include/lldb/lldb-private-types.h index 73d618d7069c..3be7003cd0fb 100644 --- a/contrib/llvm-project/lldb/include/lldb/lldb-private-types.h +++ b/contrib/llvm-project/lldb/include/lldb/lldb-private-types.h @@ -51,19 +51,15 @@ struct RegisterInfo { /// List of registers (terminated with LLDB_INVALID_REGNUM). If this value is /// not null, all registers in this list will be read first, at which point /// the value for this register will be valid. For example, the value list - /// for ah would be eax (x86) or rax (x64). - uint32_t *value_regs; // + /// for ah would be eax (x86) or rax (x64). Register numbers are + /// of eRegisterKindLLDB. If multiple registers are listed, the final + /// value will be the concatenation of them. + uint32_t *value_regs; /// List of registers (terminated with LLDB_INVALID_REGNUM). If this value is /// not null, all registers in this list will be invalidated when the value of /// this register changes. For example, the invalidate list for eax would be /// rax ax, ah, and al. uint32_t *invalidate_regs; - /// A DWARF expression that when evaluated gives the byte size of this - /// register. - const uint8_t *dynamic_size_dwarf_expr_bytes; - /// The length of the DWARF expression in bytes in the - /// dynamic_size_dwarf_expr_bytes member. - size_t dynamic_size_dwarf_len; llvm::ArrayRef<uint8_t> data(const uint8_t *context_base) const { return llvm::ArrayRef<uint8_t>(context_base + byte_offset, byte_size); diff --git a/contrib/llvm-project/lldb/include/lldb/module.modulemap b/contrib/llvm-project/lldb/include/lldb/module.modulemap index 7feea8ee99c3..c0d467a6505e 100644 --- a/contrib/llvm-project/lldb/include/lldb/module.modulemap +++ b/contrib/llvm-project/lldb/include/lldb/module.modulemap @@ -48,7 +48,6 @@ module lldb_Host { module SafeMachO { header "Host/SafeMachO.h" export * } module SocketAddress { header "Host/SocketAddress.h" export * } module Socket { header "Host/Socket.h" export * } - module StringConvert { textual header "Host/StringConvert.h" export * } module Terminal { header "Host/Terminal.h" export * } module ThreadLauncher { header "Host/ThreadLauncher.h" export * } module Time { header "Host/Time.h" export * } @@ -119,6 +118,7 @@ module lldb_Wrapper { requires cplusplus umbrella "Target" + textual header "Target/AppleArm64ExceptionClass.def" module * { export * } } } diff --git a/contrib/llvm-project/lldb/source/API/SBCommandInterpreter.cpp b/contrib/llvm-project/lldb/source/API/SBCommandInterpreter.cpp index b4a69c3e972a..3830f6ed80ba 100644 --- a/contrib/llvm-project/lldb/source/API/SBCommandInterpreter.cpp +++ b/contrib/llvm-project/lldb/source/API/SBCommandInterpreter.cpp @@ -574,12 +574,11 @@ lldb::SBCommand SBCommandInterpreter::AddMultiwordCommand(const char *name, LLDB_RECORD_METHOD(lldb::SBCommand, SBCommandInterpreter, AddMultiwordCommand, (const char *, const char *), name, help); - CommandObjectMultiword *new_command = - new CommandObjectMultiword(*m_opaque_ptr, name, help); - new_command->SetRemovable(true); - lldb::CommandObjectSP new_command_sp(new_command); - if (new_command_sp && - m_opaque_ptr->AddUserCommand(name, new_command_sp, true)) + lldb::CommandObjectSP new_command_sp( + new CommandObjectMultiword(*m_opaque_ptr, name, help)); + new_command_sp->GetAsMultiwordCommand()->SetRemovable(true); + Status add_error = m_opaque_ptr->AddUserCommand(name, new_command_sp, true); + if (add_error.Success()) return LLDB_RECORD_RESULT(lldb::SBCommand(new_command_sp)); return LLDB_RECORD_RESULT(lldb::SBCommand()); } @@ -620,8 +619,8 @@ lldb::SBCommand SBCommandInterpreter::AddCommand( *m_opaque_ptr, name, impl, help, syntax, /*flags=*/0, auto_repeat_command); - if (new_command_sp && - m_opaque_ptr->AddUserCommand(name, new_command_sp, true)) + Status add_error = m_opaque_ptr->AddUserCommand(name, new_command_sp, true); + if (add_error.Success()) return LLDB_RECORD_RESULT(lldb::SBCommand(new_command_sp)); return LLDB_RECORD_RESULT(lldb::SBCommand()); } diff --git a/contrib/llvm-project/lldb/source/API/SBDebugger.cpp b/contrib/llvm-project/lldb/source/API/SBDebugger.cpp index a854c22bb214..4bb23c3e705c 100644 --- a/contrib/llvm-project/lldb/source/API/SBDebugger.cpp +++ b/contrib/llvm-project/lldb/source/API/SBDebugger.cpp @@ -680,6 +680,21 @@ SBDebugger::GetScriptingLanguage(const char *script_language_name) { llvm::StringRef(script_language_name), eScriptLanguageDefault, nullptr); } +SBStructuredData +SBDebugger::GetScriptInterpreterInfo(lldb::ScriptLanguage language) { + LLDB_RECORD_METHOD(SBStructuredData, SBDebugger, GetScriptInterpreterInfo, + (lldb::ScriptLanguage), language); + SBStructuredData data; + if (m_opaque_sp) { + lldb_private::ScriptInterpreter *interp = + m_opaque_sp->GetScriptInterpreter(language); + if (interp) { + data.m_impl_up->SetObjectSP(interp->GetInterpreterInfo()); + } + } + return LLDB_RECORD_RESULT(data); +} + const char *SBDebugger::GetVersionString() { LLDB_RECORD_STATIC_METHOD_NO_ARGS(const char *, SBDebugger, GetVersionString); @@ -1114,7 +1129,7 @@ uint32_t SBDebugger::GetNumAvailablePlatforms() { uint32_t idx = 0; while (true) { - if (!PluginManager::GetPlatformPluginNameAtIndex(idx)) { + if (PluginManager::GetPlatformPluginNameAtIndex(idx).empty()) { break; } ++idx; @@ -1133,23 +1148,19 @@ SBStructuredData SBDebugger::GetAvailablePlatformInfoAtIndex(uint32_t idx) { if (idx == 0) { PlatformSP host_platform_sp(Platform::GetHostPlatform()); - platform_dict->AddStringItem( - name_str, host_platform_sp->GetPluginName().GetStringRef()); + platform_dict->AddStringItem(name_str, host_platform_sp->GetPluginName()); platform_dict->AddStringItem( desc_str, llvm::StringRef(host_platform_sp->GetDescription())); } else if (idx > 0) { - const char *plugin_name = + llvm::StringRef plugin_name = PluginManager::GetPlatformPluginNameAtIndex(idx - 1); - if (!plugin_name) { + if (plugin_name.empty()) { return LLDB_RECORD_RESULT(data); } platform_dict->AddStringItem(name_str, llvm::StringRef(plugin_name)); - const char *plugin_desc = + llvm::StringRef plugin_desc = PluginManager::GetPlatformPluginDescriptionAtIndex(idx - 1); - if (!plugin_desc) { - return LLDB_RECORD_RESULT(data); - } platform_dict->AddStringItem(desc_str, llvm::StringRef(plugin_desc)); } @@ -1787,6 +1798,8 @@ template <> void RegisterMethods<SBDebugger>(Registry &R) { (const char *)); LLDB_REGISTER_METHOD(lldb::ScriptLanguage, SBDebugger, GetScriptingLanguage, (const char *)); + LLDB_REGISTER_METHOD(SBStructuredData, SBDebugger, GetScriptInterpreterInfo, + (lldb::ScriptLanguage)); LLDB_REGISTER_STATIC_METHOD(const char *, SBDebugger, GetVersionString, ()); LLDB_REGISTER_STATIC_METHOD(const char *, SBDebugger, StateAsCString, (lldb::StateType)); diff --git a/contrib/llvm-project/lldb/source/API/SBFrame.cpp b/contrib/llvm-project/lldb/source/API/SBFrame.cpp index 8f9e426e066e..7107768ba884 100644 --- a/contrib/llvm-project/lldb/source/API/SBFrame.cpp +++ b/contrib/llvm-project/lldb/source/API/SBFrame.cpp @@ -633,18 +633,10 @@ SBValue SBFrame::FindValue(const char *name, ValueType value_type, { RegisterContextSP reg_ctx(frame->GetRegisterContext()); if (reg_ctx) { - const uint32_t num_regs = reg_ctx->GetRegisterCount(); - for (uint32_t reg_idx = 0; reg_idx < num_regs; ++reg_idx) { - const RegisterInfo *reg_info = - reg_ctx->GetRegisterInfoAtIndex(reg_idx); - if (reg_info && - ((reg_info->name && strcasecmp(reg_info->name, name) == 0) || - (reg_info->alt_name && - strcasecmp(reg_info->alt_name, name) == 0))) { - value_sp = ValueObjectRegister::Create(frame, reg_ctx, reg_idx); - sb_value.SetSP(value_sp); - break; - } + if (const RegisterInfo *reg_info = + reg_ctx->GetRegisterInfoByName(name)) { + value_sp = ValueObjectRegister::Create(frame, reg_ctx, reg_info); + sb_value.SetSP(value_sp); } } } break; @@ -953,18 +945,10 @@ SBValue SBFrame::FindRegister(const char *name) { if (frame) { RegisterContextSP reg_ctx(frame->GetRegisterContext()); if (reg_ctx) { - const uint32_t num_regs = reg_ctx->GetRegisterCount(); - for (uint32_t reg_idx = 0; reg_idx < num_regs; ++reg_idx) { - const RegisterInfo *reg_info = - reg_ctx->GetRegisterInfoAtIndex(reg_idx); - if (reg_info && - ((reg_info->name && strcasecmp(reg_info->name, name) == 0) || - (reg_info->alt_name && - strcasecmp(reg_info->alt_name, name) == 0))) { - value_sp = ValueObjectRegister::Create(frame, reg_ctx, reg_idx); - result.SetSP(value_sp); - break; - } + if (const RegisterInfo *reg_info = + reg_ctx->GetRegisterInfoByName(name)) { + value_sp = ValueObjectRegister::Create(frame, reg_ctx, reg_info); + result.SetSP(value_sp); } } } diff --git a/contrib/llvm-project/lldb/source/API/SBLaunchInfo.cpp b/contrib/llvm-project/lldb/source/API/SBLaunchInfo.cpp index 70cd1c6ecf74..0735e62a16cf 100644 --- a/contrib/llvm-project/lldb/source/API/SBLaunchInfo.cpp +++ b/contrib/llvm-project/lldb/source/API/SBLaunchInfo.cpp @@ -380,16 +380,18 @@ lldb::SBStructuredData SBLaunchInfo::GetScriptedProcessDictionary() const { void SBLaunchInfo::SetScriptedProcessDictionary(lldb::SBStructuredData dict) { LLDB_RECORD_METHOD(void, SBLaunchInfo, SetScriptedProcessDictionary, (lldb::SBStructuredData), dict); + if (!dict.IsValid() || !dict.m_impl_up) + return; - SBStream stream; - SBError error = dict.GetAsJSON(stream); + StructuredData::ObjectSP obj_sp = dict.m_impl_up->GetObjectSP(); - if (error.Fail()) + if (!obj_sp) return; - StructuredData::DictionarySP dict_sp; - llvm::json::OStream s(stream.ref().AsRawOstream()); - dict_sp->Serialize(s); + StructuredData::DictionarySP dict_sp = + std::make_shared<StructuredData::Dictionary>(obj_sp); + if (!dict_sp || dict_sp->GetType() == lldb::eStructuredDataTypeInvalid) + return; m_opaque_sp->SetScriptedProcessDictionarySP(dict_sp); } diff --git a/contrib/llvm-project/lldb/source/API/SBMemoryRegionInfo.cpp b/contrib/llvm-project/lldb/source/API/SBMemoryRegionInfo.cpp index ab74d559387f..9cf7874b54a3 100644 --- a/contrib/llvm-project/lldb/source/API/SBMemoryRegionInfo.cpp +++ b/contrib/llvm-project/lldb/source/API/SBMemoryRegionInfo.cpp @@ -22,6 +22,24 @@ SBMemoryRegionInfo::SBMemoryRegionInfo() : m_opaque_up(new MemoryRegionInfo()) { LLDB_RECORD_CONSTRUCTOR_NO_ARGS(SBMemoryRegionInfo); } +SBMemoryRegionInfo::SBMemoryRegionInfo(const char *name, lldb::addr_t begin, + lldb::addr_t end, uint32_t permissions, + bool mapped, bool stack_memory) + : SBMemoryRegionInfo() { + LLDB_RECORD_CONSTRUCTOR( + SBMemoryRegionInfo, + (const char *, lldb::addr_t, lldb::addr_t, uint32_t, bool, bool), name, + begin, end, permissions, mapped, stack_memory); + m_opaque_up->SetName(name); + m_opaque_up->GetRange().SetRangeBase(begin); + m_opaque_up->GetRange().SetRangeEnd(end); + m_opaque_up->SetLLDBPermissions(permissions); + m_opaque_up->SetMapped(mapped ? MemoryRegionInfo::eYes + : MemoryRegionInfo::eNo); + m_opaque_up->SetIsStackMemory(stack_memory ? MemoryRegionInfo::eYes + : MemoryRegionInfo::eNo); +} + SBMemoryRegionInfo::SBMemoryRegionInfo(const MemoryRegionInfo *lldb_object_ptr) : m_opaque_up(new MemoryRegionInfo()) { if (lldb_object_ptr) @@ -135,8 +153,8 @@ uint32_t SBMemoryRegionInfo::GetNumDirtyPages() { } addr_t SBMemoryRegionInfo::GetDirtyPageAddressAtIndex(uint32_t idx) { - LLDB_RECORD_METHOD(addr_t, SBMemoryRegionInfo, GetDirtyPageAddressAtIndex, - (uint32_t), idx); + LLDB_RECORD_METHOD(lldb::addr_t, SBMemoryRegionInfo, + GetDirtyPageAddressAtIndex, (uint32_t), idx); addr_t dirty_page_addr = LLDB_INVALID_ADDRESS; const llvm::Optional<std::vector<addr_t>> &dirty_page_list = @@ -149,6 +167,7 @@ addr_t SBMemoryRegionInfo::GetDirtyPageAddressAtIndex(uint32_t idx) { int SBMemoryRegionInfo::GetPageSize() { LLDB_RECORD_METHOD_NO_ARGS(int, SBMemoryRegionInfo, GetPageSize); + return m_opaque_up->GetPageSize(); } @@ -177,6 +196,9 @@ void RegisterMethods<SBMemoryRegionInfo>(Registry &R) { LLDB_REGISTER_CONSTRUCTOR(SBMemoryRegionInfo, ()); LLDB_REGISTER_CONSTRUCTOR(SBMemoryRegionInfo, (const lldb::SBMemoryRegionInfo &)); + LLDB_REGISTER_CONSTRUCTOR( + SBMemoryRegionInfo, + (const char *, lldb::addr_t, lldb::addr_t, uint32_t, bool, bool)); LLDB_REGISTER_METHOD( const lldb::SBMemoryRegionInfo &, SBMemoryRegionInfo, operator=,(const lldb::SBMemoryRegionInfo &)); @@ -196,6 +218,10 @@ void RegisterMethods<SBMemoryRegionInfo>(Registry &R) { LLDB_REGISTER_METHOD(const char *, SBMemoryRegionInfo, GetName, ()); LLDB_REGISTER_METHOD(bool, SBMemoryRegionInfo, GetDescription, (lldb::SBStream &)); + LLDB_REGISTER_METHOD(bool, SBMemoryRegionInfo, HasDirtyMemoryPageList, ()); + LLDB_REGISTER_METHOD(uint32_t, SBMemoryRegionInfo, GetNumDirtyPages, ()); + LLDB_REGISTER_METHOD(lldb::addr_t, SBMemoryRegionInfo, GetDirtyPageAddressAtIndex, (uint32_t)); + LLDB_REGISTER_METHOD(int, SBMemoryRegionInfo, GetPageSize, ()); } } diff --git a/contrib/llvm-project/lldb/source/API/SBMemoryRegionInfoList.cpp b/contrib/llvm-project/lldb/source/API/SBMemoryRegionInfoList.cpp index 0f3f9c1b8177..cd8fc00ffce0 100644 --- a/contrib/llvm-project/lldb/source/API/SBMemoryRegionInfoList.cpp +++ b/contrib/llvm-project/lldb/source/API/SBMemoryRegionInfoList.cpp @@ -48,6 +48,17 @@ public: void Clear() { m_regions.clear(); } + bool GetMemoryRegionContainingAddress(lldb::addr_t addr, + MemoryRegionInfo ®ion_info) { + for (auto ®ion : m_regions) { + if (region.GetRange().Contains(addr)) { + region_info = region; + return true; + } + } + return false; + } + bool GetMemoryRegionInfoAtIndex(size_t index, MemoryRegionInfo ®ion_info) { if (index >= GetSize()) @@ -103,6 +114,15 @@ uint32_t SBMemoryRegionInfoList::GetSize() const { return m_opaque_up->GetSize(); } +bool SBMemoryRegionInfoList::GetMemoryRegionContainingAddress( + lldb::addr_t addr, SBMemoryRegionInfo ®ion_info) { + LLDB_RECORD_METHOD( + bool, SBMemoryRegionInfoList, GetMemoryRegionContainingAddress, + (lldb::addr_t, lldb::SBMemoryRegionInfo &), addr, region_info); + + return m_opaque_up->GetMemoryRegionContainingAddress(addr, region_info.ref()); +} + bool SBMemoryRegionInfoList::GetMemoryRegionAtIndex( uint32_t idx, SBMemoryRegionInfo ®ion_info) { LLDB_RECORD_METHOD(bool, SBMemoryRegionInfoList, GetMemoryRegionAtIndex, @@ -153,6 +173,9 @@ void RegisterMethods<SBMemoryRegionInfoList>(Registry &R) { SBMemoryRegionInfoList, operator=,( const lldb::SBMemoryRegionInfoList &)); LLDB_REGISTER_METHOD_CONST(uint32_t, SBMemoryRegionInfoList, GetSize, ()); + LLDB_REGISTER_METHOD(bool, SBMemoryRegionInfoList, + GetMemoryRegionContainingAddress, + (lldb::addr_t, lldb::SBMemoryRegionInfo &)); LLDB_REGISTER_METHOD(bool, SBMemoryRegionInfoList, GetMemoryRegionAtIndex, (uint32_t, lldb::SBMemoryRegionInfo &)); LLDB_REGISTER_METHOD(void, SBMemoryRegionInfoList, Clear, ()); diff --git a/contrib/llvm-project/lldb/source/API/SBModule.cpp b/contrib/llvm-project/lldb/source/API/SBModule.cpp index b5b9fe16aa63..710ee8551bd6 100644 --- a/contrib/llvm-project/lldb/source/API/SBModule.cpp +++ b/contrib/llvm-project/lldb/source/API/SBModule.cpp @@ -397,11 +397,13 @@ lldb::SBSymbolContextList SBModule::FindFunctions(const char *name, lldb::SBSymbolContextList sb_sc_list; ModuleSP module_sp(GetSP()); if (name && module_sp) { - const bool symbols_ok = true; - const bool inlines_ok = true; + + ModuleFunctionSearchOptions function_options; + function_options.include_symbols = true; + function_options.include_inlines = true; FunctionNameType type = static_cast<FunctionNameType>(name_type_mask); module_sp->FindFunctions(ConstString(name), CompilerDeclContext(), type, - symbols_ok, inlines_ok, *sb_sc_list); + function_options, *sb_sc_list); } return LLDB_RECORD_RESULT(sb_sc_list); } diff --git a/contrib/llvm-project/lldb/source/API/SBPlatform.cpp b/contrib/llvm-project/lldb/source/API/SBPlatform.cpp index 496c40a0678f..d7a86f0ad1dd 100644 --- a/contrib/llvm-project/lldb/source/API/SBPlatform.cpp +++ b/contrib/llvm-project/lldb/source/API/SBPlatform.cpp @@ -458,13 +458,11 @@ const char *SBPlatform::GetOSBuild() { PlatformSP platform_sp(GetSP()); if (platform_sp) { - std::string s; - if (platform_sp->GetOSBuildString(s)) { - if (!s.empty()) { - // Const-ify the string so we don't need to worry about the lifetime of - // the string - return ConstString(s.c_str()).GetCString(); - } + std::string s = platform_sp->GetOSBuildString().getValueOr(""); + if (!s.empty()) { + // Const-ify the string so we don't need to worry about the lifetime of + // the string + return ConstString(s).GetCString(); } } return nullptr; @@ -475,13 +473,11 @@ const char *SBPlatform::GetOSDescription() { PlatformSP platform_sp(GetSP()); if (platform_sp) { - std::string s; - if (platform_sp->GetOSKernelDescription(s)) { - if (!s.empty()) { - // Const-ify the string so we don't need to worry about the lifetime of - // the string - return ConstString(s.c_str()).GetCString(); - } + std::string s = platform_sp->GetOSKernelDescription().getValueOr(""); + if (!s.empty()) { + // Const-ify the string so we don't need to worry about the lifetime of + // the string + return ConstString(s.c_str()).GetCString(); } } return nullptr; diff --git a/contrib/llvm-project/lldb/source/API/SBProcess.cpp b/contrib/llvm-project/lldb/source/API/SBProcess.cpp index 47c35a23b078..797e19462800 100644 --- a/contrib/llvm-project/lldb/source/API/SBProcess.cpp +++ b/contrib/llvm-project/lldb/source/API/SBProcess.cpp @@ -88,7 +88,7 @@ const char *SBProcess::GetPluginName() { ProcessSP process_sp(GetSP()); if (process_sp) { - return process_sp->GetPluginName().GetCString(); + return ConstString(process_sp->GetPluginName()).GetCString(); } return "<Unknown>"; } @@ -98,7 +98,7 @@ const char *SBProcess::GetShortPluginName() { ProcessSP process_sp(GetSP()); if (process_sp) { - return process_sp->GetPluginName().GetCString(); + return ConstString(process_sp->GetPluginName()).GetCString(); } return "<Unknown>"; } @@ -1228,7 +1228,7 @@ lldb::SBError SBProcess::SaveCore(const char *file_name) { FileSpec core_file(file_name); SaveCoreStyle core_style = SaveCoreStyle::eSaveCoreFull; - error.ref() = PluginManager::SaveCore(process_sp, core_file, core_style); + error.ref() = PluginManager::SaveCore(process_sp, core_file, core_style, ""); return LLDB_RECORD_RESULT(error); } diff --git a/contrib/llvm-project/lldb/source/API/SBStream.cpp b/contrib/llvm-project/lldb/source/API/SBStream.cpp index 66172d248bf3..190abd18df33 100644 --- a/contrib/llvm-project/lldb/source/API/SBStream.cpp +++ b/contrib/llvm-project/lldb/source/API/SBStream.cpp @@ -90,7 +90,7 @@ void SBStream::RedirectToFile(const char *path, bool append) { local_data = std::string( static_cast<StreamString *>(m_opaque_up.get())->GetString()); } - auto open_options = File::eOpenOptionWrite | File::eOpenOptionCanCreate; + auto open_options = File::eOpenOptionWriteOnly | File::eOpenOptionCanCreate; if (append) open_options |= File::eOpenOptionAppend; else diff --git a/contrib/llvm-project/lldb/source/API/SBTarget.cpp b/contrib/llvm-project/lldb/source/API/SBTarget.cpp index 6f0633288a2b..98158f457a04 100644 --- a/contrib/llvm-project/lldb/source/API/SBTarget.cpp +++ b/contrib/llvm-project/lldb/source/API/SBTarget.cpp @@ -73,9 +73,7 @@ using namespace lldb_private; #define DEFAULT_DISASM_BYTE_SIZE 32 -namespace { - -Status AttachToProcess(ProcessAttachInfo &attach_info, Target &target) { +static Status AttachToProcess(ProcessAttachInfo &attach_info, Target &target) { std::lock_guard<std::recursive_mutex> guard(target.GetAPIMutex()); auto process_sp = target.GetProcessSP(); @@ -94,8 +92,6 @@ Status AttachToProcess(ProcessAttachInfo &attach_info, Target &target) { return target.Attach(attach_info, nullptr); } -} // namespace - // SBTarget constructor SBTarget::SBTarget() : m_opaque_sp() { LLDB_RECORD_CONSTRUCTOR_NO_ARGS(SBTarget); @@ -217,17 +213,11 @@ SBStructuredData SBTarget::GetStatistics() { TargetSP target_sp(GetSP()); if (!target_sp) return LLDB_RECORD_RESULT(data); - - auto stats_up = std::make_unique<StructuredData::Dictionary>(); - int i = 0; - for (auto &Entry : target_sp->GetStatistics()) { - std::string Desc = lldb_private::GetStatDescription( - static_cast<lldb_private::StatisticKind>(i)); - stats_up->AddIntegerItem(Desc, Entry); - i += 1; - } - - data.m_impl_up->SetObjectSP(std::move(stats_up)); + std::string json_str = + llvm::formatv("{0:2}", + DebuggerStats::ReportStatistics(target_sp->GetDebugger(), + target_sp.get())).str(); + data.m_impl_up->SetObjectSP(StructuredData::ParseJSON(json_str)); return LLDB_RECORD_RESULT(data); } @@ -237,7 +227,7 @@ void SBTarget::SetCollectingStats(bool v) { TargetSP target_sp(GetSP()); if (!target_sp) return; - return target_sp->SetCollectingStats(v); + return DebuggerStats::SetCollectingStats(v); } bool SBTarget::GetCollectingStats() { @@ -246,7 +236,7 @@ bool SBTarget::GetCollectingStats() { TargetSP target_sp(GetSP()); if (!target_sp) return false; - return target_sp->GetCollectingStats(); + return DebuggerStats::GetCollectingStats(); } SBProcess SBTarget::LoadCore(const char *core_file) { @@ -1596,13 +1586,13 @@ void SBTarget::AppendImageSearchPath(const char *from, const char *to, if (!target_sp) return error.SetErrorString("invalid target"); - const ConstString csFrom(from), csTo(to); - if (!csFrom) + llvm::StringRef srFrom = from, srTo = to; + if (srFrom.empty()) return error.SetErrorString("<from> path can't be empty"); - if (!csTo) + if (srTo.empty()) return error.SetErrorString("<to> path can't be empty"); - target_sp->GetImageSearchPathList().Append(csFrom, csTo, true); + target_sp->GetImageSearchPathList().Append(srFrom, srTo, true); } lldb::SBModule SBTarget::AddModule(const char *path, const char *triple, @@ -1831,11 +1821,13 @@ lldb::SBSymbolContextList SBTarget::FindFunctions(const char *name, if (!target_sp) return LLDB_RECORD_RESULT(sb_sc_list); - const bool symbols_ok = true; - const bool inlines_ok = true; + ModuleFunctionSearchOptions function_options; + function_options.include_symbols = true; + function_options.include_inlines = true; + FunctionNameType mask = static_cast<FunctionNameType>(name_type_mask); - target_sp->GetImages().FindFunctions(ConstString(name), mask, symbols_ok, - inlines_ok, *sb_sc_list); + target_sp->GetImages().FindFunctions(ConstString(name), mask, + function_options, *sb_sc_list); return LLDB_RECORD_RESULT(sb_sc_list); } @@ -1851,20 +1843,25 @@ lldb::SBSymbolContextList SBTarget::FindGlobalFunctions(const char *name, llvm::StringRef name_ref(name); TargetSP target_sp(GetSP()); if (target_sp) { + ModuleFunctionSearchOptions function_options; + function_options.include_symbols = true; + function_options.include_inlines = true; + std::string regexstr; switch (matchtype) { case eMatchTypeRegex: - target_sp->GetImages().FindFunctions(RegularExpression(name_ref), true, - true, *sb_sc_list); + target_sp->GetImages().FindFunctions(RegularExpression(name_ref), + function_options, *sb_sc_list); break; case eMatchTypeStartsWith: regexstr = llvm::Regex::escape(name) + ".*"; - target_sp->GetImages().FindFunctions(RegularExpression(regexstr), true, - true, *sb_sc_list); + target_sp->GetImages().FindFunctions(RegularExpression(regexstr), + function_options, *sb_sc_list); break; default: - target_sp->GetImages().FindFunctions( - ConstString(name), eFunctionNameTypeAny, true, true, *sb_sc_list); + target_sp->GetImages().FindFunctions(ConstString(name), + eFunctionNameTypeAny, + function_options, *sb_sc_list); break; } } diff --git a/contrib/llvm-project/lldb/source/API/SBThread.cpp b/contrib/llvm-project/lldb/source/API/SBThread.cpp index e0ab8b2e9fa8..8d5b6f2a5423 100644 --- a/contrib/llvm-project/lldb/source/API/SBThread.cpp +++ b/contrib/llvm-project/lldb/source/API/SBThread.cpp @@ -513,10 +513,10 @@ SBError SBThread::ResumeNewPlan(ExecutionContext &exe_ctx, return sb_error; } - // User level plans should be Master Plans so they can be interrupted, other - // plans executed, and then a "continue" will resume the plan. + // User level plans should be Controlling Plans so they can be interrupted, + // other plans executed, and then a "continue" will resume the plan. if (new_plan != nullptr) { - new_plan->SetIsMasterPlan(true); + new_plan->SetIsControllingPlan(true); new_plan->SetOkayToDiscard(false); } diff --git a/contrib/llvm-project/lldb/source/API/liblldb-private.exports b/contrib/llvm-project/lldb/source/API/liblldb-private.exports index 9b3d86dfc892..cf1360021c6c 100644 --- a/contrib/llvm-project/lldb/source/API/liblldb-private.exports +++ b/contrib/llvm-project/lldb/source/API/liblldb-private.exports @@ -4,3 +4,4 @@ _ZN12lldb_private* _ZNK12lldb_private* init_lld* PyInit__lldb* +luaopen_lldb* diff --git a/contrib/llvm-project/lldb/source/API/liblldb.exports b/contrib/llvm-project/lldb/source/API/liblldb.exports index 3ceb562c7ed1..5835cf0a02ea 100644 --- a/contrib/llvm-project/lldb/source/API/liblldb.exports +++ b/contrib/llvm-project/lldb/source/API/liblldb.exports @@ -2,3 +2,4 @@ _ZN4lldb* _ZNK4lldb* init_lld* PyInit__lldb* +luaopen_lldb* diff --git a/contrib/llvm-project/lldb/source/API/liblldb.xcode.exports b/contrib/llvm-project/lldb/source/API/liblldb.xcode.exports deleted file mode 100644 index 9c194fa6ff67..000000000000 --- a/contrib/llvm-project/lldb/source/API/liblldb.xcode.exports +++ /dev/null @@ -1,3 +0,0 @@ -__ZN4lldb* -__ZNK4lldb* -_init_lld* diff --git a/contrib/llvm-project/lldb/source/Breakpoint/Breakpoint.cpp b/contrib/llvm-project/lldb/source/Breakpoint/Breakpoint.cpp index 8d5d5a31337c..d6acf659e852 100644 --- a/contrib/llvm-project/lldb/source/Breakpoint/Breakpoint.cpp +++ b/contrib/llvm-project/lldb/source/Breakpoint/Breakpoint.cpp @@ -439,12 +439,15 @@ BreakpointOptions &Breakpoint::GetOptions() { return m_options; } const BreakpointOptions &Breakpoint::GetOptions() const { return m_options; } void Breakpoint::ResolveBreakpoint() { - if (m_resolver_sp) + if (m_resolver_sp) { + ElapsedTime elapsed(m_resolve_time); m_resolver_sp->ResolveBreakpoint(*m_filter_sp); + } } void Breakpoint::ResolveBreakpointInModules( ModuleList &module_list, BreakpointLocationCollection &new_locations) { + ElapsedTime elapsed(m_resolve_time); m_locations.StartRecordingNewLocations(new_locations); m_resolver_sp->ResolveBreakpointInModules(*m_filter_sp, module_list); @@ -470,6 +473,7 @@ void Breakpoint::ResolveBreakpointInModules(ModuleList &module_list, } else delete new_locations_event; } else { + ElapsedTime elapsed(m_resolve_time); m_resolver_sp->ResolveBreakpointInModules(*m_filter_sp, module_list); } } @@ -602,7 +606,6 @@ void Breakpoint::ModulesChanged(ModuleList &module_list, bool load, } } -namespace { static bool SymbolContextsMightBeEquivalent(SymbolContext &old_sc, SymbolContext &new_sc) { bool equivalent_scs = false; @@ -640,7 +643,6 @@ static bool SymbolContextsMightBeEquivalent(SymbolContext &old_sc, } return equivalent_scs; } -} // anonymous namespace void Breakpoint::ModuleReplaced(ModuleSP old_module_sp, ModuleSP new_module_sp) { @@ -1088,3 +1090,34 @@ Breakpoint::BreakpointEventData::GetBreakpointLocationAtIndexFromEvent( return bp_loc_sp; } + +json::Value Breakpoint::GetStatistics() { + json::Object bp; + bp.try_emplace("id", GetID()); + bp.try_emplace("resolveTime", m_resolve_time.count()); + bp.try_emplace("numLocations", (int64_t)GetNumLocations()); + bp.try_emplace("numResolvedLocations", (int64_t)GetNumResolvedLocations()); + bp.try_emplace("internal", IsInternal()); + if (!m_kind_description.empty()) + bp.try_emplace("kindDescription", m_kind_description); + // Put the full structured data for reproducing this breakpoint in a key/value + // pair named "details". This allows the breakpoint's details to be visible + // in the stats in case we need to reproduce a breakpoint that has long + // resolve times + StructuredData::ObjectSP bp_data_sp = SerializeToStructuredData(); + if (bp_data_sp) { + std::string buffer; + llvm::raw_string_ostream ss(buffer); + json::OStream json_os(ss); + bp_data_sp->Serialize(json_os); + if (auto expected_value = llvm::json::parse(ss.str())) { + bp.try_emplace("details", std::move(*expected_value)); + } else { + std::string details_error = toString(expected_value.takeError()); + json::Object details; + details.try_emplace("error", details_error); + bp.try_emplace("details", std::move(details)); + } + } + return json::Value(std::move(bp)); +} diff --git a/contrib/llvm-project/lldb/source/Breakpoint/BreakpointID.cpp b/contrib/llvm-project/lldb/source/Breakpoint/BreakpointID.cpp index f20572144068..9bd22898196e 100644 --- a/contrib/llvm-project/lldb/source/Breakpoint/BreakpointID.cpp +++ b/contrib/llvm-project/lldb/source/Breakpoint/BreakpointID.cpp @@ -29,12 +29,7 @@ static llvm::StringRef g_range_specifiers[] = {"-", "to", "To", "TO"}; // for specifying ID ranges at a later date. bool BreakpointID::IsRangeIdentifier(llvm::StringRef str) { - for (auto spec : g_range_specifiers) { - if (spec == str) - return true; - } - - return false; + return llvm::is_contained(g_range_specifiers, str); } bool BreakpointID::IsValidIDExpression(llvm::StringRef str) { diff --git a/contrib/llvm-project/lldb/source/Breakpoint/BreakpointList.cpp b/contrib/llvm-project/lldb/source/Breakpoint/BreakpointList.cpp index a00f6bed6181..ca181ee306a4 100644 --- a/contrib/llvm-project/lldb/source/Breakpoint/BreakpointList.cpp +++ b/contrib/llvm-project/lldb/source/Breakpoint/BreakpointList.cpp @@ -101,10 +101,8 @@ void BreakpointList::RemoveAllowed(bool notify) { NotifyChange(bp_sp, eBreakpointEventTypeRemoved); } - m_breakpoints.erase( - std::remove_if(m_breakpoints.begin(), m_breakpoints.end(), - [&](const BreakpointSP &bp) { return bp->AllowDelete(); }), - m_breakpoints.end()); + llvm::erase_if(m_breakpoints, + [&](const BreakpointSP &bp) { return bp->AllowDelete(); }); } BreakpointList::bp_collection::iterator diff --git a/contrib/llvm-project/lldb/source/Breakpoint/BreakpointResolverFileLine.cpp b/contrib/llvm-project/lldb/source/Breakpoint/BreakpointResolverFileLine.cpp index 1d1ac2e90bdc..be4616064f9e 100644 --- a/contrib/llvm-project/lldb/source/Breakpoint/BreakpointResolverFileLine.cpp +++ b/contrib/llvm-project/lldb/source/Breakpoint/BreakpointResolverFileLine.cpp @@ -188,7 +188,7 @@ void BreakpointResolverFileLine::FilterContexts(SymbolContextList &sc_list, // is 0, then we can't do this calculation. That can happen if // GetStartLineSourceInfo gets an error, or if the first line number in // the function really is 0 - which happens for some languages. - + // But only do this calculation if the line number we found in the SC // was different from the one requested in the source file. If we actually // found an exact match it must be valid. @@ -229,18 +229,25 @@ Searcher::CallbackReturn BreakpointResolverFileLine::SearchCallback( const uint32_t line = m_location_spec.GetLine().getValueOr(0); const llvm::Optional<uint16_t> column = m_location_spec.GetColumn(); + // We'll create a new SourceLocationSpec that can take into account the + // relative path case, and we'll use it to resolve the symbol context + // of the CUs. FileSpec search_file_spec = m_location_spec.GetFileSpec(); const bool is_relative = search_file_spec.IsRelative(); if (is_relative) search_file_spec.GetDirectory().Clear(); + SourceLocationSpec search_location_spec( + search_file_spec, m_location_spec.GetLine().getValueOr(0), + m_location_spec.GetColumn(), m_location_spec.GetCheckInlines(), + m_location_spec.GetExactMatch()); const size_t num_comp_units = context.module_sp->GetNumCompileUnits(); for (size_t i = 0; i < num_comp_units; i++) { CompUnitSP cu_sp(context.module_sp->GetCompileUnitAtIndex(i)); if (cu_sp) { if (filter.CompUnitPasses(*cu_sp)) - cu_sp->ResolveSymbolContext(m_location_spec, eSymbolContextEverything, - sc_list); + cu_sp->ResolveSymbolContext(search_location_spec, + eSymbolContextEverything, sc_list); } } diff --git a/contrib/llvm-project/lldb/source/Breakpoint/BreakpointResolverName.cpp b/contrib/llvm-project/lldb/source/Breakpoint/BreakpointResolverName.cpp index 121ac5690d70..49087b39944d 100644 --- a/contrib/llvm-project/lldb/source/Breakpoint/BreakpointResolverName.cpp +++ b/contrib/llvm-project/lldb/source/Breakpoint/BreakpointResolverName.cpp @@ -264,8 +264,10 @@ BreakpointResolverName::SearchCallback(SearchFilter &filter, bool filter_by_cu = (filter.GetFilterRequiredItems() & eSymbolContextCompUnit) != 0; bool filter_by_language = (m_language != eLanguageTypeUnknown); - const bool include_symbols = !filter_by_cu; - const bool include_inlines = true; + + ModuleFunctionSearchOptions function_options; + function_options.include_symbols = !filter_by_cu; + function_options.include_inlines = true; switch (m_match_type) { case Breakpoint::Exact: @@ -274,8 +276,7 @@ BreakpointResolverName::SearchCallback(SearchFilter &filter, const size_t start_func_idx = func_list.GetSize(); context.module_sp->FindFunctions( lookup.GetLookupName(), CompilerDeclContext(), - lookup.GetNameTypeMask(), include_symbols, include_inlines, - func_list); + lookup.GetNameTypeMask(), function_options, func_list); const size_t end_func_idx = func_list.GetSize(); @@ -286,10 +287,7 @@ BreakpointResolverName::SearchCallback(SearchFilter &filter, break; case Breakpoint::Regexp: if (context.module_sp) { - context.module_sp->FindFunctions( - m_regex, - !filter_by_cu, // include symbols only if we aren't filtering by CU - include_inlines, func_list); + context.module_sp->FindFunctions(m_regex, function_options, func_list); } break; case Breakpoint::Glob: diff --git a/contrib/llvm-project/lldb/source/Commands/CommandCompletions.cpp b/contrib/llvm-project/lldb/source/Commands/CommandCompletions.cpp index 55018cef57d4..42b0bac717bd 100644 --- a/contrib/llvm-project/lldb/source/Commands/CommandCompletions.cpp +++ b/contrib/llvm-project/lldb/source/Commands/CommandCompletions.cpp @@ -17,6 +17,8 @@ #include "lldb/Host/FileSystem.h" #include "lldb/Interpreter/CommandCompletions.h" #include "lldb/Interpreter/CommandInterpreter.h" +#include "lldb/Interpreter/CommandObject.h" +#include "lldb/Interpreter/CommandObjectMultiword.h" #include "lldb/Interpreter/OptionValueProperties.h" #include "lldb/Symbol/CompileUnit.h" #include "lldb/Symbol/Variable.h" @@ -213,10 +215,10 @@ public: Address *addr) override { if (context.module_sp) { SymbolContextList sc_list; - const bool include_symbols = true; - const bool include_inlines = true; - context.module_sp->FindFunctions(m_regex, include_symbols, - include_inlines, sc_list); + ModuleFunctionSearchOptions function_options; + function_options.include_symbols = true; + function_options.include_inlines = true; + context.module_sp->FindFunctions(m_regex, function_options, sc_list); SymbolContext sc; // Now add the functions & symbols to the list - only add if unique: @@ -792,3 +794,60 @@ void CommandCompletions::TypeCategoryNames(CommandInterpreter &interpreter, return true; }); } + +void CommandCompletions::CompleteModifiableCmdPathArgs( + CommandInterpreter &interpreter, CompletionRequest &request, + OptionElementVector &opt_element_vector) { + // The only arguments constitute a command path, however, there might be + // options interspersed among the arguments, and we need to skip those. Do that + // by copying the args vector, and just dropping all the option bits: + Args args = request.GetParsedLine(); + std::vector<size_t> to_delete; + for (auto &elem : opt_element_vector) { + to_delete.push_back(elem.opt_pos); + if (elem.opt_arg_pos != 0) + to_delete.push_back(elem.opt_arg_pos); + } + sort(to_delete.begin(), to_delete.end(), std::greater<size_t>()); + for (size_t idx : to_delete) + args.DeleteArgumentAtIndex(idx); + + // At this point, we should only have args, so now lookup the command up to + // the cursor element. + + // There's nothing here but options. It doesn't seem very useful here to + // dump all the commands, so just return. + size_t num_args = args.GetArgumentCount(); + if (num_args == 0) + return; + + // There's just one argument, so we should complete its name: + StringList matches; + if (num_args == 1) { + interpreter.GetUserCommandObject(args.GetArgumentAtIndex(0), &matches, + nullptr); + request.AddCompletions(matches); + return; + } + + // There was more than one path element, lets find the containing command: + Status error; + CommandObjectMultiword *mwc = + interpreter.VerifyUserMultiwordCmdPath(args, true, error); + + // Something was wrong somewhere along the path, but I don't think there's + // a good way to go back and fill in the missing elements: + if (error.Fail()) + return; + + // This should never happen. We already handled the case of one argument + // above, and we can only get Success & nullptr back if there's a one-word + // leaf. + assert(mwc != nullptr); + + mwc->GetSubcommandObject(args.GetArgumentAtIndex(num_args - 1), &matches); + if (matches.GetSize() == 0) + return; + + request.AddCompletions(matches); +} diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectApropos.cpp b/contrib/llvm-project/lldb/source/Commands/CommandObjectApropos.cpp index 656487169a34..c6680f8b140d 100644 --- a/contrib/llvm-project/lldb/source/Commands/CommandObjectApropos.cpp +++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectApropos.cpp @@ -49,8 +49,8 @@ bool CommandObjectApropos::DoExecute(Args &args, CommandReturnObject &result) { StringList commands_found; StringList commands_help; - m_interpreter.FindCommandsForApropos(search_word, commands_found, - commands_help, true, true, true); + m_interpreter.FindCommandsForApropos( + search_word, commands_found, commands_help, true, true, true, true); if (commands_found.GetSize() == 0) { result.AppendMessageWithFormat("No commands found pertaining to '%s'. " diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectBreakpoint.cpp b/contrib/llvm-project/lldb/source/Commands/CommandObjectBreakpoint.cpp index 722d5c4d8f47..3f88a2fa6378 100644 --- a/contrib/llvm-project/lldb/source/Commands/CommandObjectBreakpoint.cpp +++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectBreakpoint.cpp @@ -110,7 +110,19 @@ public: case 't': { lldb::tid_t thread_id = LLDB_INVALID_THREAD_ID; if (option_arg[0] != '\0') { - if (option_arg.getAsInteger(0, thread_id)) + if (option_arg == "current") { + if (!execution_context) { + error.SetErrorStringWithFormat("No context to determine current " + "thread"); + } else { + ThreadSP ctx_thread_sp = execution_context->GetThreadSP(); + if (!ctx_thread_sp || !ctx_thread_sp->IsValid()) { + error.SetErrorStringWithFormat("No currently selected thread"); + } else { + thread_id = ctx_thread_sp->GetID(); + } + } + } else if (option_arg.getAsInteger(0, thread_id)) error.SetErrorStringWithFormat("invalid thread id string '%s'", option_arg.str().c_str()); } diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectCommands.cpp b/contrib/llvm-project/lldb/source/Commands/CommandObjectCommands.cpp index 9a8b81c007ad..1ec54cf7eded 100644 --- a/contrib/llvm-project/lldb/source/Commands/CommandObjectCommands.cpp +++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectCommands.cpp @@ -77,7 +77,7 @@ protected: public: CommandOptions() : Options(), m_stop_on_error(true), m_silent_run(false), - m_stop_on_continue(true) {} + m_stop_on_continue(true), m_cmd_relative_to_command_file(false) {} ~CommandOptions() override = default; @@ -95,6 +95,10 @@ protected: error = m_stop_on_continue.SetValueFromString(option_arg); break; + case 'C': + m_cmd_relative_to_command_file = true; + break; + case 's': error = m_silent_run.SetValueFromString(option_arg); break; @@ -110,6 +114,7 @@ protected: m_stop_on_error.Clear(); m_silent_run.Clear(); m_stop_on_continue.Clear(); + m_cmd_relative_to_command_file.Clear(); } llvm::ArrayRef<OptionDefinition> GetDefinitions() override { @@ -121,6 +126,7 @@ protected: OptionValueBoolean m_stop_on_error; OptionValueBoolean m_silent_run; OptionValueBoolean m_stop_on_continue; + OptionValueBoolean m_cmd_relative_to_command_file; }; bool DoExecute(Args &command, CommandReturnObject &result) override { @@ -131,7 +137,29 @@ protected: return false; } + FileSpec source_dir = {}; + if (m_options.m_cmd_relative_to_command_file) { + source_dir = GetDebugger().GetCommandInterpreter().GetCurrentSourceDir(); + if (!source_dir) { + result.AppendError("command source -C can only be specified " + "from a command file"); + result.SetStatus(eReturnStatusFailed); + return false; + } + } + FileSpec cmd_file(command[0].ref()); + if (source_dir) { + // Prepend the source_dir to the cmd_file path: + if (!cmd_file.IsRelative()) { + result.AppendError("command source -C can only be used " + "with a relative path."); + result.SetStatus(eReturnStatusFailed); + return false; + } + cmd_file.MakeAbsolute(source_dir); + } + FileSystem::Instance().Resolve(cmd_file); CommandInterpreterRunOptions options; @@ -415,6 +443,14 @@ protected: return false; } + if (m_interpreter.UserMultiwordCommandExists(alias_command)) { + result.AppendErrorWithFormat( + "'%s' is a user container command and cannot be overwritten.\n" + "Delete it first with 'command container delete'\n", + args[0].c_str()); + return false; + } + // Get CommandObject that is being aliased. The command name is read from // the front of raw_command_string. raw_command_string is returned with the // name of the command object stripped off the front. @@ -500,6 +536,14 @@ protected: return false; } + if (m_interpreter.UserMultiwordCommandExists(alias_command)) { + result.AppendErrorWithFormat( + "'%s' is user container command and cannot be overwritten.\n" + "Delete it first with 'command container delete'", + alias_command.c_str()); + return false; + } + CommandObjectSP command_obj_sp( m_interpreter.GetCommandSPExact(actual_command, true)); CommandObjectSP subcommand_obj_sp; @@ -1343,14 +1387,21 @@ public: CommandObjectCommandsScriptAdd(CommandInterpreter &interpreter) : CommandObjectParsed(interpreter, "command script add", "Add a scripted function as an LLDB command.", - nullptr), + "Add a scripted function as an lldb command. " + "If you provide a single argument, the command " + "will be added at the root level of the command " + "hierarchy. If there are more arguments they " + "must be a path to a user-added container " + "command, and the last element will be the new " + "command name."), IOHandlerDelegateMultiline("DONE"), m_options() { CommandArgumentEntry arg1; CommandArgumentData cmd_arg; - // Define the first (and only) variant of this arg. - cmd_arg.arg_type = eArgTypeCommandName; - cmd_arg.arg_repetition = eArgRepeatPlain; + // This is one or more command names, which form the path to the command + // you want to add. + cmd_arg.arg_type = eArgTypeCommand; + cmd_arg.arg_repetition = eArgRepeatPlus; // There is only one variant this argument could be; put it into the // argument entry. @@ -1364,6 +1415,13 @@ public: Options *GetOptions() override { return &m_options; } + void + HandleArgumentCompletion(CompletionRequest &request, + OptionElementVector &opt_element_vector) override { + CommandCompletions::CompleteModifiableCmdPathArgs(m_interpreter, request, + opt_element_vector); + } + protected: class CommandOptions : public Options { public: @@ -1390,6 +1448,9 @@ protected: if (!option_arg.empty()) m_short_help = std::string(option_arg); break; + case 'o': + m_overwrite = true; + break; case 's': m_synchronicity = (ScriptedCommandSynchronicity)OptionArgParser::ToOptionEnum( @@ -1410,6 +1471,7 @@ protected: m_class_name.clear(); m_funct_name.clear(); m_short_help.clear(); + m_overwrite = false; m_synchronicity = eScriptedCommandSynchronicitySynchronous; } @@ -1422,6 +1484,7 @@ protected: std::string m_class_name; std::string m_funct_name; std::string m_short_help; + bool m_overwrite; ScriptedCommandSynchronicity m_synchronicity = eScriptedCommandSynchronicitySynchronous; }; @@ -1456,26 +1519,36 @@ protected: CommandObjectSP command_obj_sp(new CommandObjectPythonFunction( m_interpreter, m_cmd_name, funct_name_str, m_short_help, m_synchronicity)); - - if (!m_interpreter.AddUserCommand(m_cmd_name, command_obj_sp, - true)) { - error_sp->Printf("error: unable to add selected command, didn't " - "add python command.\n"); - error_sp->Flush(); + if (!m_container) { + Status error = m_interpreter.AddUserCommand( + m_cmd_name, command_obj_sp, m_overwrite); + if (error.Fail()) { + error_sp->Printf("error: unable to add selected command: '%s'", + error.AsCString()); + error_sp->Flush(); + } + } else { + llvm::Error llvm_error = m_container->LoadUserSubcommand( + m_cmd_name, command_obj_sp, m_overwrite); + if (llvm_error) { + error_sp->Printf("error: unable to add selected command: '%s'", + llvm::toString(std::move(llvm_error)).c_str()); + error_sp->Flush(); + } } } } else { error_sp->Printf( - "error: unable to create function, didn't add python command.\n"); + "error: unable to create function, didn't add python command\n"); error_sp->Flush(); } } else { - error_sp->Printf("error: empty function, didn't add python command.\n"); + error_sp->Printf("error: empty function, didn't add python command\n"); error_sp->Flush(); } } else { error_sp->Printf( - "error: script interpreter missing, didn't add python command.\n"); + "error: script interpreter missing, didn't add python command\n"); error_sp->Flush(); } @@ -1489,31 +1562,45 @@ protected: return false; } - if (command.GetArgumentCount() != 1) { - result.AppendError("'command script add' requires one argument"); + if (command.GetArgumentCount() == 0) { + result.AppendError("'command script add' requires at least one argument"); return false; } - // Store the options in case we get multi-line input - m_cmd_name = std::string(command[0].ref()); + m_overwrite = m_options.m_overwrite; + Status path_error; + m_container = GetCommandInterpreter().VerifyUserMultiwordCmdPath( + command, true, path_error); + + if (path_error.Fail()) { + result.AppendErrorWithFormat("error in command path: %s", + path_error.AsCString()); + return false; + } + + if (!m_container) { + // This is getting inserted into the root of the interpreter. + m_cmd_name = std::string(command[0].ref()); + } else { + size_t num_args = command.GetArgumentCount(); + m_cmd_name = std::string(command[num_args - 1].ref()); + } + m_short_help.assign(m_options.m_short_help); m_synchronicity = m_options.m_synchronicity; + // Handle the case where we prompt for the script code first: + if (m_options.m_class_name.empty() && m_options.m_funct_name.empty()) { + m_interpreter.GetPythonCommandsFromIOHandler(" ", // Prompt + *this); // IOHandlerDelegate + return result.Succeeded(); + } + + CommandObjectSP new_cmd_sp; if (m_options.m_class_name.empty()) { - if (m_options.m_funct_name.empty()) { - m_interpreter.GetPythonCommandsFromIOHandler( - " ", // Prompt - *this); // IOHandlerDelegate - } else { - CommandObjectSP new_cmd(new CommandObjectPythonFunction( - m_interpreter, m_cmd_name, m_options.m_funct_name, - m_options.m_short_help, m_synchronicity)); - if (m_interpreter.AddUserCommand(m_cmd_name, new_cmd, true)) { - result.SetStatus(eReturnStatusSuccessFinishNoResult); - } else { - result.AppendError("cannot add command"); - } - } + new_cmd_sp.reset(new CommandObjectPythonFunction( + m_interpreter, m_cmd_name, m_options.m_funct_name, + m_options.m_short_help, m_synchronicity)); } else { ScriptInterpreter *interpreter = GetDebugger().GetScriptInterpreter(); if (!interpreter) { @@ -1528,21 +1615,33 @@ protected: return false; } - CommandObjectSP new_cmd(new CommandObjectScriptingObject( + new_cmd_sp.reset(new CommandObjectScriptingObject( m_interpreter, m_cmd_name, cmd_obj_sp, m_synchronicity)); - if (m_interpreter.AddUserCommand(m_cmd_name, new_cmd, true)) { - result.SetStatus(eReturnStatusSuccessFinishNoResult); - } else { - result.AppendError("cannot add command"); - } } - + + // Assume we're going to succeed... + result.SetStatus(eReturnStatusSuccessFinishNoResult); + if (!m_container) { + Status add_error = + m_interpreter.AddUserCommand(m_cmd_name, new_cmd_sp, m_overwrite); + if (add_error.Fail()) + result.AppendErrorWithFormat("cannot add command: %s", + add_error.AsCString()); + } else { + llvm::Error llvm_error = + m_container->LoadUserSubcommand(m_cmd_name, new_cmd_sp, m_overwrite); + if (llvm_error) + result.AppendErrorWithFormat("cannot add command: %s", + llvm::toString(std::move(llvm_error)).c_str()); + } return result.Succeeded(); } CommandOptions m_options; std::string m_cmd_name; + CommandObjectMultiword *m_container = nullptr; std::string m_short_help; + bool m_overwrite; ScriptedCommandSynchronicity m_synchronicity; }; @@ -1552,7 +1651,8 @@ class CommandObjectCommandsScriptList : public CommandObjectParsed { public: CommandObjectCommandsScriptList(CommandInterpreter &interpreter) : CommandObjectParsed(interpreter, "command script list", - "List defined scripted commands.", nullptr) {} + "List defined top-level scripted commands.", + nullptr) {} ~CommandObjectCommandsScriptList() override = default; @@ -1600,14 +1700,17 @@ protected: class CommandObjectCommandsScriptDelete : public CommandObjectParsed { public: CommandObjectCommandsScriptDelete(CommandInterpreter &interpreter) - : CommandObjectParsed(interpreter, "command script delete", - "Delete a scripted command.", nullptr) { + : CommandObjectParsed( + interpreter, "command script delete", + "Delete a scripted command by specifying the path to the command.", + nullptr) { CommandArgumentEntry arg1; CommandArgumentData cmd_arg; - // Define the first (and only) variant of this arg. - cmd_arg.arg_type = eArgTypeCommandName; - cmd_arg.arg_repetition = eArgRepeatPlain; + // This is a list of command names forming the path to the command + // to be deleted. + cmd_arg.arg_type = eArgTypeCommand; + cmd_arg.arg_repetition = eArgRepeatPlus; // There is only one variant this argument could be; put it into the // argument entry. @@ -1622,30 +1725,86 @@ public: void HandleArgumentCompletion(CompletionRequest &request, OptionElementVector &opt_element_vector) override { - if (!m_interpreter.HasCommands() || request.GetCursorIndex() != 0) - return; - - for (const auto &c : m_interpreter.GetUserCommands()) - request.TryCompleteCurrentArg(c.first, c.second->GetHelp()); + CommandCompletions::CompleteModifiableCmdPathArgs(m_interpreter, request, + opt_element_vector); } protected: bool DoExecute(Args &command, CommandReturnObject &result) override { - if (command.GetArgumentCount() != 1) { - result.AppendError("'command script delete' requires one argument"); + llvm::StringRef root_cmd = command[0].ref(); + size_t num_args = command.GetArgumentCount(); + + if (root_cmd.empty()) { + result.AppendErrorWithFormat("empty root command name"); + return false; + } + if (!m_interpreter.HasUserCommands() && + !m_interpreter.HasUserMultiwordCommands()) { + result.AppendErrorWithFormat("can only delete user defined commands, " + "but no user defined commands found"); return false; } - auto cmd_name = command[0].ref(); + CommandObjectSP cmd_sp = m_interpreter.GetCommandSPExact(root_cmd); + if (!cmd_sp) { + result.AppendErrorWithFormat("command '%s' not found.", + command[0].c_str()); + return false; + } + if (!cmd_sp->IsUserCommand()) { + result.AppendErrorWithFormat("command '%s' is not a user command.", + command[0].c_str()); + return false; + } + if (cmd_sp->GetAsMultiwordCommand() && num_args == 1) { + result.AppendErrorWithFormat("command '%s' is a multi-word command.\n " + "Delete with \"command container delete\"", + command[0].c_str()); + return false; + } - if (cmd_name.empty() || !m_interpreter.HasUserCommands() || - !m_interpreter.UserCommandExists(cmd_name)) { - result.AppendErrorWithFormat("command %s not found", command[0].c_str()); + if (command.GetArgumentCount() == 1) { + m_interpreter.RemoveUser(root_cmd); + result.SetStatus(eReturnStatusSuccessFinishResult); + return true; + } + // We're deleting a command from a multiword command. Verify the command + // path: + Status error; + CommandObjectMultiword *container = + GetCommandInterpreter().VerifyUserMultiwordCmdPath(command, true, + error); + if (error.Fail()) { + result.AppendErrorWithFormat("could not resolve command path: %s", + error.AsCString()); + return false; + } + if (!container) { + // This means that command only had a leaf command, so the container is + // the root. That should have been handled above. + result.AppendErrorWithFormat("could not find a container for '%s'", + command[0].c_str()); + return false; + } + const char *leaf_cmd = command[num_args - 1].c_str(); + llvm::Error llvm_error = container->RemoveUserSubcommand(leaf_cmd, + /* multiword not okay */ false); + if (llvm_error) { + result.AppendErrorWithFormat("could not delete command '%s': %s", + leaf_cmd, + llvm::toString(std::move(llvm_error)).c_str()); return false; } - m_interpreter.RemoveUser(cmd_name); + Stream &out_stream = result.GetOutputStream(); + + out_stream << "Deleted command:"; + for (size_t idx = 0; idx < num_args; idx++) { + out_stream << ' '; + out_stream << command[idx].c_str(); + } + out_stream << '\n'; result.SetStatus(eReturnStatusSuccessFinishResult); return true; } @@ -1682,6 +1841,271 @@ public: ~CommandObjectMultiwordCommandsScript() override = default; }; +#pragma mark CommandObjectCommandContainer +#define LLDB_OPTIONS_container_add +#include "CommandOptions.inc" + +class CommandObjectCommandsContainerAdd : public CommandObjectParsed { +public: + CommandObjectCommandsContainerAdd(CommandInterpreter &interpreter) + : CommandObjectParsed( + interpreter, "command container add", + "Add a container command to lldb. Adding to built-" + "in container commands is not allowed.", + "command container add [[path1]...] container-name") { + CommandArgumentEntry arg1; + CommandArgumentData cmd_arg; + + // This is one or more command names, which form the path to the command + // you want to add. + cmd_arg.arg_type = eArgTypeCommand; + cmd_arg.arg_repetition = eArgRepeatPlus; + + // There is only one variant this argument could be; put it into the + // argument entry. + arg1.push_back(cmd_arg); + + // Push the data for the first argument into the m_arguments vector. + m_arguments.push_back(arg1); + } + + ~CommandObjectCommandsContainerAdd() override = default; + + Options *GetOptions() override { return &m_options; } + + void + HandleArgumentCompletion(CompletionRequest &request, + OptionElementVector &opt_element_vector) override { + CommandCompletions::CompleteModifiableCmdPathArgs(m_interpreter, request, + opt_element_vector); + } + +protected: + class CommandOptions : public Options { + public: + CommandOptions() : Options(), m_short_help(), m_long_help() {} + + ~CommandOptions() override = default; + + Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, + ExecutionContext *execution_context) override { + Status error; + const int short_option = m_getopt_table[option_idx].val; + + switch (short_option) { + case 'h': + if (!option_arg.empty()) + m_short_help = std::string(option_arg); + break; + case 'o': + m_overwrite = true; + break; + case 'H': + if (!option_arg.empty()) + m_long_help = std::string(option_arg); + break; + default: + llvm_unreachable("Unimplemented option"); + } + + return error; + } + + void OptionParsingStarting(ExecutionContext *execution_context) override { + m_short_help.clear(); + m_long_help.clear(); + m_overwrite = false; + } + + llvm::ArrayRef<OptionDefinition> GetDefinitions() override { + return llvm::makeArrayRef(g_container_add_options); + } + + // Instance variables to hold the values for command options. + + std::string m_short_help; + std::string m_long_help; + bool m_overwrite = false; + }; + bool DoExecute(Args &command, CommandReturnObject &result) override { + size_t num_args = command.GetArgumentCount(); + + if (num_args == 0) { + result.AppendError("no command was specified"); + return false; + } + + if (num_args == 1) { + // We're adding this as a root command, so use the interpreter. + const char *cmd_name = command.GetArgumentAtIndex(0); + auto cmd_sp = CommandObjectSP(new CommandObjectMultiword( + GetCommandInterpreter(), cmd_name, m_options.m_short_help.c_str(), + m_options.m_long_help.c_str())); + cmd_sp->GetAsMultiwordCommand()->SetRemovable(true); + Status add_error = GetCommandInterpreter().AddUserCommand( + cmd_name, cmd_sp, m_options.m_overwrite); + if (add_error.Fail()) { + result.AppendErrorWithFormat("error adding command: %s", + add_error.AsCString()); + return false; + } + result.SetStatus(eReturnStatusSuccessFinishNoResult); + return true; + } + + // We're adding this to a subcommand, first find the subcommand: + Status path_error; + CommandObjectMultiword *add_to_me = + GetCommandInterpreter().VerifyUserMultiwordCmdPath(command, true, + path_error); + + if (!add_to_me) { + result.AppendErrorWithFormat("error adding command: %s", + path_error.AsCString()); + return false; + } + + const char *cmd_name = command.GetArgumentAtIndex(num_args - 1); + auto cmd_sp = CommandObjectSP(new CommandObjectMultiword( + GetCommandInterpreter(), cmd_name, m_options.m_short_help.c_str(), + m_options.m_long_help.c_str())); + llvm::Error llvm_error = + add_to_me->LoadUserSubcommand(cmd_name, cmd_sp, m_options.m_overwrite); + if (llvm_error) { + result.AppendErrorWithFormat("error adding subcommand: %s", + llvm::toString(std::move(llvm_error)).c_str()); + return false; + } + + result.SetStatus(eReturnStatusSuccessFinishNoResult); + return true; + } + +private: + CommandOptions m_options; +}; + +#define LLDB_OPTIONS_multiword_delete +#include "CommandOptions.inc" +class CommandObjectCommandsContainerDelete : public CommandObjectParsed { +public: + CommandObjectCommandsContainerDelete(CommandInterpreter &interpreter) + : CommandObjectParsed( + interpreter, "command container delete", + "Delete a container command previously added to " + "lldb.", + "command container delete [[path1] ...] container-cmd") { + CommandArgumentEntry arg1; + CommandArgumentData cmd_arg; + + // This is one or more command names, which form the path to the command + // you want to add. + cmd_arg.arg_type = eArgTypeCommand; + cmd_arg.arg_repetition = eArgRepeatPlus; + + // There is only one variant this argument could be; put it into the + // argument entry. + arg1.push_back(cmd_arg); + + // Push the data for the first argument into the m_arguments vector. + m_arguments.push_back(arg1); + } + + ~CommandObjectCommandsContainerDelete() override = default; + + void + HandleArgumentCompletion(CompletionRequest &request, + OptionElementVector &opt_element_vector) override { + CommandCompletions::CompleteModifiableCmdPathArgs(m_interpreter, request, + opt_element_vector); + } + +protected: + bool DoExecute(Args &command, CommandReturnObject &result) override { + size_t num_args = command.GetArgumentCount(); + + if (num_args == 0) { + result.AppendError("No command was specified."); + return false; + } + + if (num_args == 1) { + // We're removing a root command, so we need to delete it from the + // interpreter. + const char *cmd_name = command.GetArgumentAtIndex(0); + // Let's do a little more work here so we can do better error reporting. + CommandInterpreter &interp = GetCommandInterpreter(); + CommandObjectSP cmd_sp = interp.GetCommandSPExact(cmd_name); + if (!cmd_sp) { + result.AppendErrorWithFormat("container command %s doesn't exist.", + cmd_name); + return false; + } + if (!cmd_sp->IsUserCommand()) { + result.AppendErrorWithFormat( + "container command %s is not a user command", cmd_name); + return false; + } + if (!cmd_sp->GetAsMultiwordCommand()) { + result.AppendErrorWithFormat("command %s is not a container command", + cmd_name); + return false; + } + + bool did_remove = GetCommandInterpreter().RemoveUserMultiword(cmd_name); + if (!did_remove) { + result.AppendErrorWithFormat("error removing command %s.", cmd_name); + return false; + } + + result.SetStatus(eReturnStatusSuccessFinishNoResult); + return true; + } + + // We're removing a subcommand, first find the subcommand's owner: + Status path_error; + CommandObjectMultiword *container = + GetCommandInterpreter().VerifyUserMultiwordCmdPath(command, true, + path_error); + + if (!container) { + result.AppendErrorWithFormat("error removing container command: %s", + path_error.AsCString()); + return false; + } + const char *leaf = command.GetArgumentAtIndex(num_args - 1); + llvm::Error llvm_error = + container->RemoveUserSubcommand(leaf, /* multiword okay */ true); + if (llvm_error) { + result.AppendErrorWithFormat("error removing container command: %s", + llvm::toString(std::move(llvm_error)).c_str()); + return false; + } + result.SetStatus(eReturnStatusSuccessFinishNoResult); + return true; + } +}; + +class CommandObjectCommandContainer : public CommandObjectMultiword { +public: + CommandObjectCommandContainer(CommandInterpreter &interpreter) + : CommandObjectMultiword( + interpreter, "command container", + "Commands for adding container commands to lldb. " + "Container commands are containers for other commands. You can" + "add nested container commands by specifying a command path, but " + "but you can't add commands into the built-in command hierarchy.", + "command container <subcommand> [<subcommand-options>]") { + LoadSubCommand("add", CommandObjectSP(new CommandObjectCommandsContainerAdd( + interpreter))); + LoadSubCommand( + "delete", + CommandObjectSP(new CommandObjectCommandsContainerDelete(interpreter))); + } + + ~CommandObjectCommandContainer() override = default; +}; + #pragma mark CommandObjectMultiwordCommands // CommandObjectMultiwordCommands @@ -1699,6 +2123,8 @@ CommandObjectMultiwordCommands::CommandObjectMultiwordCommands( new CommandObjectCommandsUnalias(interpreter))); LoadSubCommand("delete", CommandObjectSP(new CommandObjectCommandsDelete(interpreter))); + LoadSubCommand("container", CommandObjectSP(new CommandObjectCommandContainer( + interpreter))); LoadSubCommand( "regex", CommandObjectSP(new CommandObjectCommandsAddRegex(interpreter))); LoadSubCommand( diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectDisassemble.cpp b/contrib/llvm-project/lldb/source/Commands/CommandObjectDisassemble.cpp index 5e73fb8218ab..02a16622c76b 100644 --- a/contrib/llvm-project/lldb/source/Commands/CommandObjectDisassemble.cpp +++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectDisassemble.cpp @@ -322,13 +322,15 @@ CommandObjectDisassemble::GetCurrentLineRanges() { llvm::Expected<std::vector<AddressRange>> CommandObjectDisassemble::GetNameRanges(CommandReturnObject &result) { ConstString name(m_options.func_name.c_str()); - const bool include_symbols = true; - const bool include_inlines = true; + + ModuleFunctionSearchOptions function_options; + function_options.include_symbols = true; + function_options.include_inlines = true; // Find functions matching the given name. SymbolContextList sc_list; - GetSelectedTarget().GetImages().FindFunctions( - name, eFunctionNameTypeAuto, include_symbols, include_inlines, sc_list); + GetSelectedTarget().GetImages().FindFunctions(name, eFunctionNameTypeAuto, + function_options, sc_list); std::vector<AddressRange> ranges; llvm::Error range_errs = llvm::Error::success(); diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectExpression.cpp b/contrib/llvm-project/lldb/source/Commands/CommandObjectExpression.cpp index bf62f3f297cc..9d13ccab6d3e 100644 --- a/contrib/llvm-project/lldb/source/Commands/CommandObjectExpression.cpp +++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectExpression.cpp @@ -421,9 +421,8 @@ bool CommandObjectExpression::EvaluateExpression(llvm::StringRef expr, // We only tell you about the FixIt if we applied it. The compiler errors // will suggest the FixIt if it parsed. if (!m_fixed_expression.empty() && target.GetEnableNotifyAboutFixIts()) { - if (success == eExpressionCompleted) - error_stream.Printf(" Fix-it applied, fixed expression was: \n %s\n", - m_fixed_expression.c_str()); + error_stream.Printf(" Fix-it applied, fixed expression was: \n %s\n", + m_fixed_expression.c_str()); } if (result_valobj_sp) { @@ -660,13 +659,8 @@ bool CommandObjectExpression::DoExecute(llvm::StringRef command, fixed_command.append(m_fixed_expression); history.AppendString(fixed_command); } - // Increment statistics to record this expression evaluation success. - target.IncrementStats(StatisticKind::ExpressionSuccessful); return true; } - - // Increment statistics to record this expression evaluation failure. - target.IncrementStats(StatisticKind::ExpressionFailure); result.SetStatus(eReturnStatusFailed); return false; } diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectFrame.cpp b/contrib/llvm-project/lldb/source/Commands/CommandObjectFrame.cpp index d90e357bf1aa..2b9f5316409f 100644 --- a/contrib/llvm-project/lldb/source/Commands/CommandObjectFrame.cpp +++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectFrame.cpp @@ -14,6 +14,7 @@ #include "lldb/Host/OptionParser.h" #include "lldb/Interpreter/CommandInterpreter.h" #include "lldb/Interpreter/CommandReturnObject.h" +#include "lldb/Interpreter/OptionArgParser.h" #include "lldb/Interpreter/OptionGroupFormat.h" #include "lldb/Interpreter/OptionGroupValueObjectDisplay.h" #include "lldb/Interpreter/OptionGroupVariable.h" @@ -104,7 +105,7 @@ public: CommandObjectFrameDiagnose(CommandInterpreter &interpreter) : CommandObjectParsed(interpreter, "frame diagnose", - "Try to determine what path path the current stop " + "Try to determine what path the current stop " "location used to get to a register or address", nullptr, eCommandRequiresThread | eCommandTryTargetAPILock | @@ -707,11 +708,11 @@ protected: // Increment statistics. bool res = result.Succeeded(); - Target &target = GetSelectedOrDummyTarget(); + TargetStats &target_stats = GetSelectedOrDummyTarget().GetStatistics(); if (res) - target.IncrementStats(StatisticKind::FrameVarSuccess); + target_stats.GetFrameVariableStats().NotifySuccess(); else - target.IncrementStats(StatisticKind::FrameVarFailure); + target_stats.GetFrameVariableStats().NotifyFailure(); return res; } @@ -739,6 +740,17 @@ private: const int short_option = m_getopt_table[option_idx].val; switch (short_option) { + case 'f': { + bool value, success; + value = OptionArgParser::ToBoolean(option_arg, true, &success); + if (success) { + m_first_instruction_only = value; + } else { + error.SetErrorStringWithFormat( + "invalid boolean value '%s' passed for -f option", + option_arg.str().c_str()); + } + } break; case 'l': m_class_name = std::string(option_arg); break; @@ -763,6 +775,7 @@ private: m_symbols.clear(); m_class_name = ""; m_regex = false; + m_first_instruction_only = true; } llvm::ArrayRef<OptionDefinition> GetDefinitions() override { @@ -774,6 +787,7 @@ private: std::string m_module; std::vector<std::string> m_symbols; bool m_regex; + bool m_first_instruction_only; }; CommandOptions m_options; @@ -883,13 +897,13 @@ bool CommandObjectFrameRecognizerAdd::DoExecute(Args &command, auto func = RegularExpressionSP(new RegularExpression(m_options.m_symbols.front())); GetSelectedOrDummyTarget().GetFrameRecognizerManager().AddRecognizer( - recognizer_sp, module, func); + recognizer_sp, module, func, m_options.m_first_instruction_only); } else { auto module = ConstString(m_options.m_module); std::vector<ConstString> symbols(m_options.m_symbols.begin(), m_options.m_symbols.end()); GetSelectedOrDummyTarget().GetFrameRecognizerManager().AddRecognizer( - recognizer_sp, module, symbols); + recognizer_sp, module, symbols, m_options.m_first_instruction_only); } #endif diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectHelp.cpp b/contrib/llvm-project/lldb/source/Commands/CommandObjectHelp.cpp index 4643ee30f0f9..8c24efaa08ee 100644 --- a/contrib/llvm-project/lldb/source/Commands/CommandObjectHelp.cpp +++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectHelp.cpp @@ -51,8 +51,9 @@ CommandObjectHelp::CommandObjectHelp(CommandInterpreter &interpreter) CommandArgumentEntry arg; CommandArgumentData command_arg; - // Define the first (and only) variant of this arg. - command_arg.arg_type = eArgTypeCommandName; + // A list of command names forming a path to the command we want help on. + // No names is allowed - in which case we dump the top-level help. + command_arg.arg_type = eArgTypeCommand; command_arg.arg_repetition = eArgRepeatStar; // There is only one variant this argument could be; put it into the argument @@ -85,8 +86,10 @@ bool CommandObjectHelp::DoExecute(Args &command, CommandReturnObject &result) { uint32_t cmd_types = CommandInterpreter::eCommandTypesBuiltin; if (m_options.m_show_aliases) cmd_types |= CommandInterpreter::eCommandTypesAliases; - if (m_options.m_show_user_defined) + if (m_options.m_show_user_defined) { cmd_types |= CommandInterpreter::eCommandTypesUserDef; + cmd_types |= CommandInterpreter::eCommandTypesUserMW; + } if (m_options.m_show_hidden) cmd_types |= CommandInterpreter::eCommandTypesHidden; diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectMemory.cpp b/contrib/llvm-project/lldb/source/Commands/CommandObjectMemory.cpp index 5487d94c9019..f27d4bd7e4b2 100644 --- a/contrib/llvm-project/lldb/source/Commands/CommandObjectMemory.cpp +++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectMemory.cpp @@ -754,7 +754,7 @@ protected: if (outfile_spec) { File::OpenOptions open_options = - File::eOpenOptionWrite | File::eOpenOptionCanCreate; + File::eOpenOptionWriteOnly | File::eOpenOptionCanCreate; const bool append = m_outfile_options.GetAppend().GetCurrentValue(); open_options |= append ? File::eOpenOptionAppend : File::eOpenOptionTruncate; diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectMultiword.cpp b/contrib/llvm-project/lldb/source/Commands/CommandObjectMultiword.cpp index a523fd0b1560..e800bcc12bd3 100644 --- a/contrib/llvm-project/lldb/source/Commands/CommandObjectMultiword.cpp +++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectMultiword.cpp @@ -26,36 +26,48 @@ CommandObjectMultiword::CommandObjectMultiword(CommandInterpreter &interpreter, CommandObjectMultiword::~CommandObjectMultiword() = default; +CommandObjectSP +CommandObjectMultiword::GetSubcommandSPExact(llvm::StringRef sub_cmd) { + if (m_subcommand_dict.empty()) + return {}; + + auto pos = m_subcommand_dict.find(std::string(sub_cmd)); + if (pos == m_subcommand_dict.end()) + return {}; + + return pos->second; +} + CommandObjectSP CommandObjectMultiword::GetSubcommandSP(llvm::StringRef sub_cmd, StringList *matches) { - CommandObjectSP return_cmd_sp; + if (m_subcommand_dict.empty()) + return {}; + + CommandObjectSP return_cmd_sp = GetSubcommandSPExact(sub_cmd); + if (return_cmd_sp) { + if (matches) + matches->AppendString(sub_cmd); + return return_cmd_sp; + } + CommandObject::CommandMap::iterator pos; - if (!m_subcommand_dict.empty()) { + StringList local_matches; + if (matches == nullptr) + matches = &local_matches; + int num_matches = + AddNamesMatchingPartialString(m_subcommand_dict, sub_cmd, *matches); + + if (num_matches == 1) { + // Cleaner, but slightly less efficient would be to call back into this + // function, since I now know I have an exact match... + + sub_cmd = matches->GetStringAtIndex(0); pos = m_subcommand_dict.find(std::string(sub_cmd)); - if (pos != m_subcommand_dict.end()) { - // An exact match; append the sub_cmd to the 'matches' string list. - if (matches) - matches->AppendString(sub_cmd); + if (pos != m_subcommand_dict.end()) return_cmd_sp = pos->second; - } else { - StringList local_matches; - if (matches == nullptr) - matches = &local_matches; - int num_matches = - AddNamesMatchingPartialString(m_subcommand_dict, sub_cmd, *matches); - - if (num_matches == 1) { - // Cleaner, but slightly less efficient would be to call back into this - // function, since I now know I have an exact match... - - sub_cmd = matches->GetStringAtIndex(0); - pos = m_subcommand_dict.find(std::string(sub_cmd)); - if (pos != m_subcommand_dict.end()) - return_cmd_sp = pos->second; - } - } } + return return_cmd_sp; } @@ -66,9 +78,9 @@ CommandObjectMultiword::GetSubcommandObject(llvm::StringRef sub_cmd, } bool CommandObjectMultiword::LoadSubCommand(llvm::StringRef name, - const CommandObjectSP &cmd_obj) { - if (cmd_obj) - assert((&GetCommandInterpreter() == &cmd_obj->GetCommandInterpreter()) && + const CommandObjectSP &cmd_obj_sp) { + if (cmd_obj_sp) + lldbassert((&GetCommandInterpreter() == &cmd_obj_sp->GetCommandInterpreter()) && "tried to add a CommandObject from a different interpreter"); CommandMap::iterator pos; @@ -76,13 +88,76 @@ bool CommandObjectMultiword::LoadSubCommand(llvm::StringRef name, pos = m_subcommand_dict.find(std::string(name)); if (pos == m_subcommand_dict.end()) { - m_subcommand_dict[std::string(name)] = cmd_obj; + m_subcommand_dict[std::string(name)] = cmd_obj_sp; } else success = false; return success; } +llvm::Error CommandObjectMultiword::LoadUserSubcommand( + llvm::StringRef name, const CommandObjectSP &cmd_obj_sp, bool can_replace) { + Status result; + if (cmd_obj_sp) + lldbassert((&GetCommandInterpreter() == &cmd_obj_sp->GetCommandInterpreter()) && + "tried to add a CommandObject from a different interpreter"); + if (!IsUserCommand()) { + return llvm::createStringError(llvm::inconvertibleErrorCode(), + "can't add a user subcommand to a builtin container command."); + } + // Make sure this a user command if it isn't already: + cmd_obj_sp->SetIsUserCommand(true); + + std::string str_name(name); + + auto pos = m_subcommand_dict.find(str_name); + if (pos == m_subcommand_dict.end()) { + m_subcommand_dict[str_name] = cmd_obj_sp; + return llvm::Error::success(); + } + + const char *error_str = nullptr; + if (!can_replace) + error_str = "sub-command already exists"; + if (!(*pos).second->IsUserCommand()) + error_str = "can't replace a builtin subcommand"; + + if (error_str) { + return llvm::createStringError(llvm::inconvertibleErrorCode(), error_str); + } + m_subcommand_dict[str_name] = cmd_obj_sp; + return llvm::Error::success(); +} + +llvm::Error CommandObjectMultiword::RemoveUserSubcommand(llvm::StringRef cmd_name, + bool must_be_multiword) { + CommandMap::iterator pos; + std::string str_name(cmd_name); + + pos = m_subcommand_dict.find(str_name); + if (pos == m_subcommand_dict.end()) { + return llvm::createStringError(llvm::inconvertibleErrorCode(),"subcommand '%s' not found.", + str_name.c_str()); + } + if (!(*pos).second->IsUserCommand()) { + return llvm::createStringError(llvm::inconvertibleErrorCode(),"subcommand '%s' not a user command.", + str_name.c_str()); + } + + if (must_be_multiword && !(*pos).second->IsMultiwordObject()) { + return llvm::createStringError(llvm::inconvertibleErrorCode(),"subcommand '%s' is not a container command", + str_name.c_str()); + } + if (!must_be_multiword && (*pos).second->IsMultiwordObject()) { + return llvm::createStringError(llvm::inconvertibleErrorCode(),"subcommand '%s' is not a user command", + str_name.c_str()); + } + + m_subcommand_dict.erase(pos); + + return llvm::Error::success(); +} + bool CommandObjectMultiword::Execute(const char *args_string, CommandReturnObject &result) { Args args(args_string); diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectPlatform.cpp b/contrib/llvm-project/lldb/source/Commands/CommandObjectPlatform.cpp index bf23c4552aa8..10dd87824911 100644 --- a/contrib/llvm-project/lldb/source/Commands/CommandObjectPlatform.cpp +++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectPlatform.cpp @@ -211,20 +211,18 @@ protected: ostrm.Printf("Available platforms:\n"); PlatformSP host_platform_sp(Platform::GetHostPlatform()); - ostrm.Printf("%s: %s\n", host_platform_sp->GetPluginName().GetCString(), + ostrm.Format("{0}: {1}\n", host_platform_sp->GetPluginName(), host_platform_sp->GetDescription()); uint32_t idx; for (idx = 0; true; ++idx) { - const char *plugin_name = + llvm::StringRef plugin_name = PluginManager::GetPlatformPluginNameAtIndex(idx); - if (plugin_name == nullptr) + if (plugin_name.empty()) break; - const char *plugin_desc = + llvm::StringRef plugin_desc = PluginManager::GetPlatformPluginDescriptionAtIndex(idx); - if (plugin_desc == nullptr) - break; - ostrm.Printf("%s: %s\n", plugin_name, plugin_desc); + ostrm.Format("{0}: {1}\n", plugin_name, plugin_desc); } if (idx == 0) { @@ -346,8 +344,8 @@ protected: if (error.Success()) { Stream &ostrm = result.GetOutputStream(); if (hostname.empty()) - ostrm.Printf("Disconnected from \"%s\"\n", - platform_sp->GetPluginName().GetCString()); + ostrm.Format("Disconnected from \"{0}\"\n", + platform_sp->GetPluginName()); else ostrm.Printf("Disconnected from \"%s\"\n", hostname.c_str()); result.SetStatus(eReturnStatusSuccessFinishResult); @@ -356,9 +354,8 @@ protected: } } else { // Not connected... - result.AppendErrorWithFormat( - "not connected to '%s'", - platform_sp->GetPluginName().GetCString()); + result.AppendErrorWithFormatv("not connected to '{0}'", + platform_sp->GetPluginName()); } } else { // Bad args @@ -498,8 +495,7 @@ public: lldb::eFilePermissionsWorldRead; lldb::user_id_t fd = platform_sp->OpenFile( FileSpec(cmd_line), - File::eOpenOptionRead | File::eOpenOptionWrite | - File::eOpenOptionAppend | File::eOpenOptionCanCreate, + File::eOpenOptionReadWrite | File::eOpenOptionCanCreate, perms, error); if (error.Success()) { result.AppendMessageWithFormat("File Descriptor = %" PRIu64 "\n", fd); @@ -589,11 +585,15 @@ public: } std::string buffer(m_options.m_count, 0); Status error; - uint32_t retcode = platform_sp->ReadFile( + uint64_t retcode = platform_sp->ReadFile( fd, m_options.m_offset, &buffer[0], m_options.m_count, error); - result.AppendMessageWithFormat("Return = %d\n", retcode); - result.AppendMessageWithFormat("Data = \"%s\"\n", buffer.c_str()); - result.SetStatus(eReturnStatusSuccessFinishResult); + if (retcode != UINT64_MAX) { + result.AppendMessageWithFormat("Return = %" PRIu64 "\n", retcode); + result.AppendMessageWithFormat("Data = \"%s\"\n", buffer.c_str()); + result.SetStatus(eReturnStatusSuccessFinishResult); + } else { + result.AppendError(error.AsCString()); + } } else { result.AppendError("no platform currently selected\n"); } @@ -678,11 +678,15 @@ public: cmd_line); return result.Succeeded(); } - uint32_t retcode = + uint64_t retcode = platform_sp->WriteFile(fd, m_options.m_offset, &m_options.m_data[0], m_options.m_data.size(), error); - result.AppendMessageWithFormat("Return = %d\n", retcode); - result.SetStatus(eReturnStatusSuccessFinishResult); + if (retcode != UINT64_MAX) { + result.AppendMessageWithFormat("Return = %" PRIu64 "\n", retcode); + result.SetStatus(eReturnStatusSuccessFinishResult); + } else { + result.AppendError(error.AsCString()); + } } else { result.AppendError("no platform currently selected\n"); } @@ -919,13 +923,159 @@ public: } }; +// "platform get-permissions remote-file-path" +class CommandObjectPlatformGetPermissions : public CommandObjectParsed { +public: + CommandObjectPlatformGetPermissions(CommandInterpreter &interpreter) + : CommandObjectParsed(interpreter, "platform get-permissions", + "Get the file permission bits from the remote end.", + "platform get-permissions <remote-file-spec>", 0) { + SetHelpLong( + R"(Examples: + +(lldb) platform get-permissions /the/remote/file/path + + Get the file permissions from the remote end with path /the/remote/file/path.)"); + + CommandArgumentEntry arg1; + CommandArgumentData file_arg_remote; + + // Define the first (and only) variant of this arg. + file_arg_remote.arg_type = eArgTypeFilename; + file_arg_remote.arg_repetition = eArgRepeatPlain; + // There is only one variant this argument could be; put it into the + // argument entry. + arg1.push_back(file_arg_remote); + + // Push the data for the first argument into the m_arguments vector. + m_arguments.push_back(arg1); + } + + ~CommandObjectPlatformGetPermissions() override = default; + + void + HandleArgumentCompletion(CompletionRequest &request, + OptionElementVector &opt_element_vector) override { + if (request.GetCursorIndex() != 0) + return; + + CommandCompletions::InvokeCommonCompletionCallbacks( + GetCommandInterpreter(), CommandCompletions::eRemoteDiskFileCompletion, + request, nullptr); + } + + bool DoExecute(Args &args, CommandReturnObject &result) override { + // If the number of arguments is incorrect, issue an error message. + if (args.GetArgumentCount() != 1) { + result.AppendError("required argument missing; specify the source file " + "path as the only argument"); + return false; + } + + PlatformSP platform_sp( + GetDebugger().GetPlatformList().GetSelectedPlatform()); + if (platform_sp) { + std::string remote_file_path(args.GetArgumentAtIndex(0)); + uint32_t permissions; + Status error = platform_sp->GetFilePermissions(FileSpec(remote_file_path), + permissions); + if (error.Success()) { + result.AppendMessageWithFormat( + "File permissions of %s (remote): 0o%04" PRIo32 "\n", + remote_file_path.c_str(), permissions); + result.SetStatus(eReturnStatusSuccessFinishResult); + } else + result.AppendError(error.AsCString()); + } else { + result.AppendError("no platform currently selected\n"); + } + return result.Succeeded(); + } +}; + +// "platform file-exists remote-file-path" +class CommandObjectPlatformFileExists : public CommandObjectParsed { +public: + CommandObjectPlatformFileExists(CommandInterpreter &interpreter) + : CommandObjectParsed(interpreter, "platform file-exists", + "Check if the file exists on the remote end.", + "platform file-exists <remote-file-spec>", 0) { + SetHelpLong( + R"(Examples: + +(lldb) platform file-exists /the/remote/file/path + + Check if /the/remote/file/path exists on the remote end.)"); + + CommandArgumentEntry arg1; + CommandArgumentData file_arg_remote; + + // Define the first (and only) variant of this arg. + file_arg_remote.arg_type = eArgTypeFilename; + file_arg_remote.arg_repetition = eArgRepeatPlain; + // There is only one variant this argument could be; put it into the + // argument entry. + arg1.push_back(file_arg_remote); + + // Push the data for the first argument into the m_arguments vector. + m_arguments.push_back(arg1); + } + + ~CommandObjectPlatformFileExists() override = default; + + void + HandleArgumentCompletion(CompletionRequest &request, + OptionElementVector &opt_element_vector) override { + if (request.GetCursorIndex() != 0) + return; + + CommandCompletions::InvokeCommonCompletionCallbacks( + GetCommandInterpreter(), CommandCompletions::eRemoteDiskFileCompletion, + request, nullptr); + } + + bool DoExecute(Args &args, CommandReturnObject &result) override { + // If the number of arguments is incorrect, issue an error message. + if (args.GetArgumentCount() != 1) { + result.AppendError("required argument missing; specify the source file " + "path as the only argument"); + return false; + } + + PlatformSP platform_sp( + GetDebugger().GetPlatformList().GetSelectedPlatform()); + if (platform_sp) { + std::string remote_file_path(args.GetArgumentAtIndex(0)); + bool exists = platform_sp->GetFileExists(FileSpec(remote_file_path)); + result.AppendMessageWithFormat( + "File %s (remote) %s\n", + remote_file_path.c_str(), exists ? "exists" : "does not exist"); + result.SetStatus(eReturnStatusSuccessFinishResult); + } else { + result.AppendError("no platform currently selected\n"); + } + return result.Succeeded(); + } +}; + // "platform put-file" class CommandObjectPlatformPutFile : public CommandObjectParsed { public: CommandObjectPlatformPutFile(CommandInterpreter &interpreter) : CommandObjectParsed( interpreter, "platform put-file", - "Transfer a file from this system to the remote end.", nullptr, 0) { + "Transfer a file from this system to the remote end.", + "platform put-file <source> [<destination>]", 0) { + SetHelpLong( + R"(Examples: + +(lldb) platform put-file /source/foo.txt /destination/bar.txt + +(lldb) platform put-file /source/foo.txt + + Relative source file paths are resolved against lldb's local working directory. + + Omitting the destination places the file in the platform working directory.)"); } ~CommandObjectPlatformPutFile() override = default; @@ -1029,7 +1179,7 @@ protected: target->GetRunArguments(m_options.launch_info.GetArguments()); ProcessSP process_sp(platform_sp->DebugProcess( - m_options.launch_info, debugger, target, error)); + m_options.launch_info, debugger, *target, error)); if (process_sp && process_sp->IsAlive()) { result.SetStatus(eReturnStatusSuccessFinishNoResult); return true; @@ -1136,15 +1286,14 @@ protected: if (matches == 0) { if (match_desc) - result.AppendErrorWithFormat( - "no processes were found that %s \"%s\" on the \"%s\" " + result.AppendErrorWithFormatv( + "no processes were found that {0} \"{1}\" on the \"{2}\" " "platform\n", - match_desc, match_name, - platform_sp->GetPluginName().GetCString()); + match_desc, match_name, platform_sp->GetPluginName()); else - result.AppendErrorWithFormat( - "no processes were found on the \"%s\" platform\n", - platform_sp->GetPluginName().GetCString()); + result.AppendErrorWithFormatv( + "no processes were found on the \"{0}\" platform\n", + platform_sp->GetPluginName()); } else { result.AppendMessageWithFormat( "%u matching process%s found on \"%s\"", matches, @@ -1390,9 +1539,8 @@ protected: } } else { // Not connected... - result.AppendErrorWithFormat( - "not connected to '%s'", - platform_sp->GetPluginName().GetCString()); + result.AppendErrorWithFormatv("not connected to '{0}'", + platform_sp->GetPluginName()); } } else { // No args @@ -1752,8 +1900,12 @@ CommandObjectPlatform::CommandObjectPlatform(CommandInterpreter &interpreter) CommandObjectSP(new CommandObjectPlatformMkDir(interpreter))); LoadSubCommand("file", CommandObjectSP(new CommandObjectPlatformFile(interpreter))); + LoadSubCommand("file-exists", + CommandObjectSP(new CommandObjectPlatformFileExists(interpreter))); LoadSubCommand("get-file", CommandObjectSP(new CommandObjectPlatformGetFile( interpreter))); + LoadSubCommand("get-permissions", + CommandObjectSP(new CommandObjectPlatformGetPermissions(interpreter))); LoadSubCommand("get-size", CommandObjectSP(new CommandObjectPlatformGetSize( interpreter))); LoadSubCommand("put-file", CommandObjectSP(new CommandObjectPlatformPutFile( diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectProcess.cpp b/contrib/llvm-project/lldb/source/Commands/CommandObjectProcess.cpp index 7aaba3731500..5fd1718e8484 100644 --- a/contrib/llvm-project/lldb/source/Commands/CommandObjectProcess.cpp +++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectProcess.cpp @@ -159,7 +159,12 @@ protected: // If our listener is nullptr, users aren't allows to launch ModuleSP exe_module_sp = target->GetExecutableModule(); - if (exe_module_sp == nullptr) { + // If the target already has an executable module, then use that. If it + // doesn't then someone must be trying to launch using a path that will + // make sense to the remote stub, but doesn't exist on the local host. + // In that case use the ExecutableFile that was set in the target's + // ProcessLaunchInfo. + if (exe_module_sp == nullptr && !target->GetProcessLaunchInfo().GetExecutableFile()) { result.AppendError("no file in target, create a debug target using the " "'target create' command"); return false; @@ -170,8 +175,6 @@ protected: if (!StopProcessIfNecessary(m_exe_ctx.GetProcessPtr(), state, result)) return false; - llvm::StringRef target_settings_argv0 = target->GetArg0(); - // Determine whether we will disable ASLR or leave it in the default state // (i.e. enabled if the platform supports it). First check if the process // launch options explicitly turn on/off @@ -216,14 +219,22 @@ protected: m_options.launch_info.GetEnvironment().insert(target_env.begin(), target_env.end()); + llvm::StringRef target_settings_argv0 = target->GetArg0(); + if (!target_settings_argv0.empty()) { m_options.launch_info.GetArguments().AppendArgument( target_settings_argv0); - m_options.launch_info.SetExecutableFile( - exe_module_sp->GetPlatformFileSpec(), false); + if (exe_module_sp) + m_options.launch_info.SetExecutableFile( + exe_module_sp->GetPlatformFileSpec(), false); + else + m_options.launch_info.SetExecutableFile(target->GetProcessLaunchInfo().GetExecutableFile(), false); } else { - m_options.launch_info.SetExecutableFile( - exe_module_sp->GetPlatformFileSpec(), true); + if (exe_module_sp) + m_options.launch_info.SetExecutableFile( + exe_module_sp->GetPlatformFileSpec(), true); + else + m_options.launch_info.SetExecutableFile(target->GetProcessLaunchInfo().GetExecutableFile(), true); } if (launch_args.GetArgumentCount() == 0) { @@ -250,11 +261,20 @@ protected: llvm::StringRef data = stream.GetString(); if (!data.empty()) result.AppendMessage(data); - const char *archname = - exe_module_sp->GetArchitecture().GetArchitectureName(); - result.AppendMessageWithFormat( - "Process %" PRIu64 " launched: '%s' (%s)\n", process_sp->GetID(), - exe_module_sp->GetFileSpec().GetPath().c_str(), archname); + // If we didn't have a local executable, then we wouldn't have had an + // executable module before launch. + if (!exe_module_sp) + exe_module_sp = target->GetExecutableModule(); + if (!exe_module_sp) { + result.AppendWarning("Could not get executable module after launch."); + } else { + + const char *archname = + exe_module_sp->GetArchitecture().GetArchitectureName(); + result.AppendMessageWithFormat( + "Process %" PRIu64 " launched: '%s' (%s)\n", process_sp->GetID(), + exe_module_sp->GetFileSpec().GetPath().c_str(), archname); + } result.SetStatus(eReturnStatusSuccessFinishResult); result.SetDidChangeProcessState(true); } else { @@ -398,9 +418,10 @@ protected: } StreamString stream; + ProcessSP process_sp; const auto error = target->Attach(m_options.attach_info, &stream); if (error.Success()) { - ProcessSP process_sp(target->GetProcessSP()); + process_sp = target->GetProcessSP(); if (process_sp) { result.AppendMessage(stream.GetString()); result.SetStatus(eReturnStatusSuccessFinishNoResult); @@ -452,8 +473,13 @@ protected: // This supports the use-case scenario of immediately continuing the // process once attached. - if (m_options.attach_info.GetContinueOnceAttached()) - m_interpreter.HandleCommand("process continue", eLazyBoolNo, result); + if (m_options.attach_info.GetContinueOnceAttached()) { + // We have made a process but haven't told the interpreter about it yet, + // so CheckRequirements will fail for "process continue". Set the override + // here: + ExecutionContext exe_ctx(process_sp); + m_interpreter.HandleCommand("process continue", eLazyBoolNo, exe_ctx, result); + } return result.Succeeded(); } @@ -1166,7 +1192,9 @@ protected: static constexpr OptionEnumValueElement g_corefile_save_style[] = { {eSaveCoreFull, "full", "Create a core file with all memory saved"}, {eSaveCoreDirtyOnly, "modified-memory", - "Create a corefile with only modified memory saved"}}; + "Create a corefile with only modified memory saved"}, + {eSaveCoreStackOnly, "stack", + "Create a corefile with only stack memory saved"}}; static constexpr OptionEnumValues SaveCoreStyles() { return OptionEnumValues(g_corefile_save_style); @@ -1178,12 +1206,13 @@ static constexpr OptionEnumValues SaveCoreStyles() { class CommandObjectProcessSaveCore : public CommandObjectParsed { public: CommandObjectProcessSaveCore(CommandInterpreter &interpreter) - : CommandObjectParsed(interpreter, "process save-core", - "Save the current process as a core file using an " - "appropriate file type.", - "process save-core [-s corefile-style] FILE", - eCommandRequiresProcess | eCommandTryTargetAPILock | - eCommandProcessMustBeLaunched) {} + : CommandObjectParsed( + interpreter, "process save-core", + "Save the current process as a core file using an " + "appropriate file type.", + "process save-core [-s corefile-style -p plugin-name] FILE", + eCommandRequiresProcess | eCommandTryTargetAPILock | + eCommandProcessMustBeLaunched) {} ~CommandObjectProcessSaveCore() override = default; @@ -1206,6 +1235,9 @@ public: Status error; switch (short_option) { + case 'p': + m_requested_plugin_name = option_arg.str(); + break; case 's': m_requested_save_core_style = (lldb::SaveCoreStyle)OptionArgParser::ToOptionEnum( @@ -1221,10 +1253,12 @@ public: void OptionParsingStarting(ExecutionContext *execution_context) override { m_requested_save_core_style = eSaveCoreUnspecified; + m_requested_plugin_name.clear(); } // Instance variables to hold the values for command options. SaveCoreStyle m_requested_save_core_style; + std::string m_requested_plugin_name; }; protected: @@ -1235,13 +1269,15 @@ protected: FileSpec output_file(command.GetArgumentAtIndex(0)); SaveCoreStyle corefile_style = m_options.m_requested_save_core_style; Status error = - PluginManager::SaveCore(process_sp, output_file, corefile_style); + PluginManager::SaveCore(process_sp, output_file, corefile_style, + m_options.m_requested_plugin_name); if (error.Success()) { - if (corefile_style == SaveCoreStyle::eSaveCoreDirtyOnly) { + if (corefile_style == SaveCoreStyle::eSaveCoreDirtyOnly || + corefile_style == SaveCoreStyle::eSaveCoreStackOnly) { result.AppendMessageWithFormat( - "\nModified-memory only corefile " - "created. This corefile may not show \n" - "library/framework/app binaries " + "\nModified-memory or stack-memory only corefile " + "created. This corefile may \n" + "not show library/framework/app binaries " "on a different system, or when \n" "those binaries have " "been updated/modified. Copies are not included\n" @@ -1641,6 +1677,80 @@ protected: } }; +// CommandObjectProcessTraceSave +#define LLDB_OPTIONS_process_trace_save +#include "CommandOptions.inc" + +#pragma mark CommandObjectProcessTraceSave + +class CommandObjectProcessTraceSave : public CommandObjectParsed { +public: + class CommandOptions : public Options { + public: + CommandOptions() : Options() { OptionParsingStarting(nullptr); } + + Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, + ExecutionContext *execution_context) override { + Status error; + const int short_option = m_getopt_table[option_idx].val; + + switch (short_option) { + + case 'd': { + m_directory.SetFile(option_arg, FileSpec::Style::native); + FileSystem::Instance().Resolve(m_directory); + break; + } + default: + llvm_unreachable("Unimplemented option"); + } + return error; + } + + void OptionParsingStarting(ExecutionContext *execution_context) override{}; + + llvm::ArrayRef<OptionDefinition> GetDefinitions() override { + return llvm::makeArrayRef(g_process_trace_save_options); + }; + + FileSpec m_directory; + }; + + Options *GetOptions() override { return &m_options; } + CommandObjectProcessTraceSave(CommandInterpreter &interpreter) + : CommandObjectParsed( + interpreter, "process trace save", + "Save the trace of the current process in the specified directory. " + "The directory will be created if needed. " + "This will also create a file <directory>/trace.json with the main " + "properties of the trace session, along with others files which " + "contain the actual trace data. The trace.json file can be used " + "later as input for the \"trace load\" command to load the trace " + "in LLDB", + "process trace save [<cmd-options>]", + eCommandRequiresProcess | eCommandTryTargetAPILock | + eCommandProcessMustBeLaunched | eCommandProcessMustBePaused | + eCommandProcessMustBeTraced) {} + + ~CommandObjectProcessTraceSave() override = default; + +protected: + bool DoExecute(Args &command, CommandReturnObject &result) override { + ProcessSP process_sp = m_exe_ctx.GetProcessSP(); + + TraceSP trace_sp = process_sp->GetTarget().GetTrace(); + + if (llvm::Error err = trace_sp->SaveLiveTraceToDisk(m_options.m_directory)) + result.AppendError(toString(std::move(err))); + else + result.SetStatus(eReturnStatusSuccessFinishResult); + + return result.Succeeded(); + } + + CommandOptions m_options; +}; + // CommandObjectProcessTraceStop class CommandObjectProcessTraceStop : public CommandObjectParsed { public: @@ -1678,6 +1788,8 @@ public: : CommandObjectMultiword( interpreter, "trace", "Commands for tracing the current process.", "process trace <subcommand> [<subcommand objects>]") { + LoadSubCommand("save", CommandObjectSP( + new CommandObjectProcessTraceSave(interpreter))); LoadSubCommand("start", CommandObjectSP(new CommandObjectProcessTraceStart( interpreter))); LoadSubCommand("stop", CommandObjectSP( diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectSettings.cpp b/contrib/llvm-project/lldb/source/Commands/CommandObjectSettings.cpp index cd79680e31f7..13ff27c78dea 100644 --- a/contrib/llvm-project/lldb/source/Commands/CommandObjectSettings.cpp +++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectSettings.cpp @@ -369,7 +369,7 @@ protected: FileSpec file_spec(m_options.m_filename); FileSystem::Instance().Resolve(file_spec); std::string path(file_spec.GetPath()); - auto options = File::eOpenOptionWrite | File::eOpenOptionCanCreate; + auto options = File::eOpenOptionWriteOnly | File::eOpenOptionCanCreate; if (m_options.m_append) options |= File::eOpenOptionAppend; else diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectSource.cpp b/contrib/llvm-project/lldb/source/Commands/CommandObjectSource.cpp index 7a0338e35bc7..fb33f41b8ef9 100644 --- a/contrib/llvm-project/lldb/source/Commands/CommandObjectSource.cpp +++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectSource.cpp @@ -374,13 +374,16 @@ protected: Target *target = m_exe_ctx.GetTargetPtr(); uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize(); + ModuleFunctionSearchOptions function_options; + function_options.include_symbols = false; + function_options.include_inlines = true; + // Note: module_list can't be const& because FindFunctionSymbols isn't // const. ModuleList module_list = (m_module_list.GetSize() > 0) ? m_module_list : target->GetImages(); - module_list.FindFunctions(name, eFunctionNameTypeAuto, - /*include_symbols=*/false, - /*include_inlines=*/true, sc_list_funcs); + module_list.FindFunctions(name, eFunctionNameTypeAuto, function_options, + sc_list_funcs); size_t num_matches = sc_list_funcs.GetSize(); if (!num_matches) { @@ -874,12 +877,13 @@ protected: void FindMatchingFunctions(Target *target, ConstString name, SymbolContextList &sc_list) { // Displaying the source for a symbol: - bool include_inlines = true; - bool include_symbols = false; - if (m_options.num_lines == 0) m_options.num_lines = 10; + ModuleFunctionSearchOptions function_options; + function_options.include_symbols = true; + function_options.include_inlines = false; + const size_t num_modules = m_options.modules.size(); if (num_modules > 0) { ModuleList matching_modules; @@ -889,15 +893,14 @@ protected: ModuleSpec module_spec(module_file_spec); matching_modules.Clear(); target->GetImages().FindModules(module_spec, matching_modules); + matching_modules.FindFunctions(name, eFunctionNameTypeAuto, - include_symbols, include_inlines, - sc_list); + function_options, sc_list); } } } else { target->GetImages().FindFunctions(name, eFunctionNameTypeAuto, - include_symbols, include_inlines, - sc_list); + function_options, sc_list); } } diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectStats.cpp b/contrib/llvm-project/lldb/source/Commands/CommandObjectStats.cpp index 23c7dbbaf373..f32d559ca039 100644 --- a/contrib/llvm-project/lldb/source/Commands/CommandObjectStats.cpp +++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectStats.cpp @@ -7,6 +7,8 @@ //===----------------------------------------------------------------------===// #include "CommandObjectStats.h" +#include "lldb/Core/Debugger.h" +#include "lldb/Host/OptionParser.h" #include "lldb/Interpreter/CommandReturnObject.h" #include "lldb/Target/Target.h" @@ -24,14 +26,12 @@ public: protected: bool DoExecute(Args &command, CommandReturnObject &result) override { - Target &target = GetSelectedOrDummyTarget(); - - if (target.GetCollectingStats()) { + if (DebuggerStats::GetCollectingStats()) { result.AppendError("statistics already enabled"); return false; } - target.SetCollectingStats(true); + DebuggerStats::SetCollectingStats(true); result.SetStatus(eReturnStatusSuccessFinishResult); return true; } @@ -48,44 +48,74 @@ public: protected: bool DoExecute(Args &command, CommandReturnObject &result) override { - Target &target = GetSelectedOrDummyTarget(); - - if (!target.GetCollectingStats()) { + if (!DebuggerStats::GetCollectingStats()) { result.AppendError("need to enable statistics before disabling them"); return false; } - target.SetCollectingStats(false); + DebuggerStats::SetCollectingStats(false); result.SetStatus(eReturnStatusSuccessFinishResult); return true; } }; +#define LLDB_OPTIONS_statistics_dump +#include "CommandOptions.inc" + class CommandObjectStatsDump : public CommandObjectParsed { + class CommandOptions : public Options { + public: + CommandOptions() : Options() { OptionParsingStarting(nullptr); } + + Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, + ExecutionContext *execution_context) override { + Status error; + const int short_option = m_getopt_table[option_idx].val; + + switch (short_option) { + case 'a': + m_all_targets = true; + break; + default: + llvm_unreachable("Unimplemented option"); + } + return error; + } + + void OptionParsingStarting(ExecutionContext *execution_context) override { + m_all_targets = false; + } + + llvm::ArrayRef<OptionDefinition> GetDefinitions() override { + return llvm::makeArrayRef(g_statistics_dump_options); + } + + bool m_all_targets = false; + }; + public: CommandObjectStatsDump(CommandInterpreter &interpreter) - : CommandObjectParsed(interpreter, "dump", "Dump statistics results", - nullptr, eCommandProcessMustBePaused) {} + : CommandObjectParsed( + interpreter, "statistics dump", "Dump metrics in JSON format", + "statistics dump [<options>]", eCommandRequiresTarget) {} ~CommandObjectStatsDump() override = default; + Options *GetOptions() override { return &m_options; } + protected: bool DoExecute(Args &command, CommandReturnObject &result) override { - Target &target = GetSelectedOrDummyTarget(); - - uint32_t i = 0; - for (auto &stat : target.GetStatistics()) { - result.AppendMessageWithFormat( - "%s : %u\n", - lldb_private::GetStatDescription( - static_cast<lldb_private::StatisticKind>(i)) - .c_str(), - stat); - i += 1; - } + Target *target = nullptr; + if (!m_options.m_all_targets) + target = m_exe_ctx.GetTargetPtr(); + + result.AppendMessageWithFormatv( + "{0:2}", DebuggerStats::ReportStatistics(GetDebugger(), target)); result.SetStatus(eReturnStatusSuccessFinishResult); return true; } + + CommandOptions m_options; }; CommandObjectStats::CommandObjectStats(CommandInterpreter &interpreter) diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectTarget.cpp b/contrib/llvm-project/lldb/source/Commands/CommandObjectTarget.cpp index b25514b1ffbc..2a42eb22938d 100644 --- a/contrib/llvm-project/lldb/source/Commands/CommandObjectTarget.cpp +++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectTarget.cpp @@ -272,7 +272,7 @@ protected: if (core_file) { auto file = FileSystem::Instance().Open( - core_file, lldb_private::File::eOpenOptionRead); + core_file, lldb_private::File::eOpenOptionReadOnly); if (!file) { result.AppendErrorWithFormatv("Cannot open '{0}': {1}.", @@ -286,7 +286,7 @@ protected: FileSpec symfile(m_symbol_file.GetOptionValue().GetCurrentValue()); if (symfile) { auto file = FileSystem::Instance().Open( - symfile, lldb_private::File::eOpenOptionRead); + symfile, lldb_private::File::eOpenOptionReadOnly); if (!file) { result.AppendErrorWithFormatv("Cannot open '{0}': {1}.", @@ -1047,8 +1047,7 @@ protected: } bool last_pair = ((argc - i) == 2); target->GetImageSearchPathList().Append( - ConstString(from), ConstString(to), - last_pair); // Notify if this is the last pair + from, to, last_pair); // Notify if this is the last pair result.SetStatus(eReturnStatusSuccessFinishNoResult); } else { if (from[0]) @@ -1175,8 +1174,8 @@ protected: if (from[0] && to[0]) { bool last_pair = ((argc - i) == 2); - target->GetImageSearchPathList().Insert( - ConstString(from), ConstString(to), insert_idx, last_pair); + target->GetImageSearchPathList().Insert(from, to, insert_idx, + last_pair); result.SetStatus(eReturnStatusSuccessFinishNoResult); } else { if (from[0]) @@ -1570,20 +1569,18 @@ static void DumpSymbolContextList(ExecutionContextScope *exe_scope, static size_t LookupFunctionInModule(CommandInterpreter &interpreter, Stream &strm, Module *module, const char *name, bool name_is_regex, - bool include_inlines, bool include_symbols, + const ModuleFunctionSearchOptions &options, bool verbose) { if (module && name && name[0]) { SymbolContextList sc_list; size_t num_matches = 0; if (name_is_regex) { RegularExpression function_name_regex((llvm::StringRef(name))); - module->FindFunctions(function_name_regex, include_symbols, - include_inlines, sc_list); + module->FindFunctions(function_name_regex, options, sc_list); } else { ConstString function_name(name); module->FindFunctions(function_name, CompilerDeclContext(), - eFunctionNameTypeAuto, include_symbols, - include_inlines, sc_list); + eFunctionNameTypeAuto, options, sc_list); } num_matches = sc_list.GetSize(); if (num_matches) { @@ -2836,6 +2833,7 @@ protected: OptionGroupUInt64 m_slide_option; }; +#pragma mark CommandObjectTargetModulesList // List images with associated information #define LLDB_OPTIONS_target_modules_list #include "CommandOptions.inc" @@ -3281,8 +3279,11 @@ protected: if (m_options.m_type == eLookupTypeFunctionOrSymbol) { ConstString function_name(m_options.m_str.c_str()); + ModuleFunctionSearchOptions function_options; + function_options.include_symbols = true; + function_options.include_inlines = false; target->GetImages().FindFunctions(function_name, eFunctionNameTypeAuto, - true, false, sc_list); + function_options, sc_list); } else if (m_options.m_type == eLookupTypeAddress && target) { Address addr; if (target->GetSectionLoadList().ResolveLoadAddress(m_options.m_addr, @@ -3753,13 +3754,15 @@ public: case eLookupTypeFunctionOrSymbol: case eLookupTypeFunction: if (!m_options.m_str.empty()) { - if (LookupFunctionInModule( - m_interpreter, result.GetOutputStream(), module, - m_options.m_str.c_str(), m_options.m_use_regex, - m_options.m_include_inlines, - m_options.m_type == - eLookupTypeFunctionOrSymbol, // include symbols - m_options.m_verbose)) { + ModuleFunctionSearchOptions function_options; + function_options.include_symbols = + m_options.m_type == eLookupTypeFunctionOrSymbol; + function_options.include_inlines = m_options.m_include_inlines; + + if (LookupFunctionInModule(m_interpreter, result.GetOutputStream(), + module, m_options.m_str.c_str(), + m_options.m_use_regex, function_options, + m_options.m_verbose)) { result.SetStatus(eReturnStatusSuccessFinishResult); return true; } @@ -3959,8 +3962,12 @@ public: "name."), m_current_frame_option( LLDB_OPT_SET_2, false, "frame", 'F', - "Locate the debug symbols for the currently selected frame.", - false, true) + "Locate the debug symbols for the currently selected frame.", false, + true), + m_current_stack_option(LLDB_OPT_SET_2, false, "stack", 'S', + "Locate the debug symbols for every frame in " + "the current call stack.", + false, true) { m_option_group.Append(&m_uuid_option_group, LLDB_OPT_SET_ALL, @@ -3968,6 +3975,8 @@ public: m_option_group.Append(&m_file_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1); m_option_group.Append(&m_current_frame_option, LLDB_OPT_SET_2, LLDB_OPT_SET_2); + m_option_group.Append(&m_current_stack_option, LLDB_OPT_SET_2, + LLDB_OPT_SET_2); m_option_group.Finalize(); } @@ -4140,6 +4149,167 @@ protected: return false; } + bool DownloadObjectAndSymbolFile(ModuleSpec &module_spec, + CommandReturnObject &result, bool &flush) { + if (Symbols::DownloadObjectAndSymbolFile(module_spec)) { + if (module_spec.GetSymbolFileSpec()) + return AddModuleSymbols(m_exe_ctx.GetTargetPtr(), module_spec, flush, + result); + } + return false; + } + + bool AddSymbolsForUUID(CommandReturnObject &result, bool &flush) { + assert(m_uuid_option_group.GetOptionValue().OptionWasSet()); + + ModuleSpec module_spec; + module_spec.GetUUID() = + m_uuid_option_group.GetOptionValue().GetCurrentValue(); + + if (!DownloadObjectAndSymbolFile(module_spec, result, flush)) { + StreamString error_strm; + error_strm.PutCString("unable to find debug symbols for UUID "); + module_spec.GetUUID().Dump(&error_strm); + result.AppendError(error_strm.GetString()); + return false; + } + + return true; + } + + bool AddSymbolsForFile(CommandReturnObject &result, bool &flush) { + assert(m_file_option.GetOptionValue().OptionWasSet()); + + ModuleSpec module_spec; + module_spec.GetFileSpec() = + m_file_option.GetOptionValue().GetCurrentValue(); + + Target *target = m_exe_ctx.GetTargetPtr(); + ModuleSP module_sp(target->GetImages().FindFirstModule(module_spec)); + if (module_sp) { + module_spec.GetFileSpec() = module_sp->GetFileSpec(); + module_spec.GetPlatformFileSpec() = module_sp->GetPlatformFileSpec(); + module_spec.GetUUID() = module_sp->GetUUID(); + module_spec.GetArchitecture() = module_sp->GetArchitecture(); + } else { + module_spec.GetArchitecture() = target->GetArchitecture(); + } + + if (!DownloadObjectAndSymbolFile(module_spec, result, flush)) { + StreamString error_strm; + error_strm.PutCString( + "unable to find debug symbols for the executable file "); + error_strm << module_spec.GetFileSpec(); + result.AppendError(error_strm.GetString()); + return false; + } + + return true; + } + + bool AddSymbolsForFrame(CommandReturnObject &result, bool &flush) { + assert(m_current_frame_option.GetOptionValue().OptionWasSet()); + + Process *process = m_exe_ctx.GetProcessPtr(); + if (!process) { + result.AppendError( + "a process must exist in order to use the --frame option"); + return false; + } + + const StateType process_state = process->GetState(); + if (!StateIsStoppedState(process_state, true)) { + result.AppendErrorWithFormat("process is not stopped: %s", + StateAsCString(process_state)); + return false; + } + + StackFrame *frame = m_exe_ctx.GetFramePtr(); + if (!frame) { + result.AppendError("invalid current frame"); + return false; + } + + ModuleSP frame_module_sp( + frame->GetSymbolContext(eSymbolContextModule).module_sp); + if (!frame_module_sp) { + result.AppendError("frame has no module"); + return false; + } + + ModuleSpec module_spec; + module_spec.GetUUID() = frame_module_sp->GetUUID(); + + if (FileSystem::Instance().Exists(frame_module_sp->GetPlatformFileSpec())) { + module_spec.GetArchitecture() = frame_module_sp->GetArchitecture(); + module_spec.GetFileSpec() = frame_module_sp->GetPlatformFileSpec(); + } + + if (!DownloadObjectAndSymbolFile(module_spec, result, flush)) { + result.AppendError("unable to find debug symbols for the current frame"); + return false; + } + + return true; + } + + bool AddSymbolsForStack(CommandReturnObject &result, bool &flush) { + assert(m_current_stack_option.GetOptionValue().OptionWasSet()); + + Process *process = m_exe_ctx.GetProcessPtr(); + if (!process) { + result.AppendError( + "a process must exist in order to use the --stack option"); + return false; + } + + const StateType process_state = process->GetState(); + if (!StateIsStoppedState(process_state, true)) { + result.AppendErrorWithFormat("process is not stopped: %s", + StateAsCString(process_state)); + return false; + } + + Thread *thread = m_exe_ctx.GetThreadPtr(); + if (!thread) { + result.AppendError("invalid current thread"); + return false; + } + + bool symbols_found = false; + uint32_t frame_count = thread->GetStackFrameCount(); + for (uint32_t i = 0; i < frame_count; ++i) { + lldb::StackFrameSP frame_sp = thread->GetStackFrameAtIndex(i); + + ModuleSP frame_module_sp( + frame_sp->GetSymbolContext(eSymbolContextModule).module_sp); + if (!frame_module_sp) + continue; + + ModuleSpec module_spec; + module_spec.GetUUID() = frame_module_sp->GetUUID(); + + if (FileSystem::Instance().Exists( + frame_module_sp->GetPlatformFileSpec())) { + module_spec.GetArchitecture() = frame_module_sp->GetArchitecture(); + module_spec.GetFileSpec() = frame_module_sp->GetPlatformFileSpec(); + } + + bool current_frame_flush = false; + if (DownloadObjectAndSymbolFile(module_spec, result, current_frame_flush)) + symbols_found = true; + flush |= current_frame_flush; + } + + if (!symbols_found) { + result.AppendError( + "unable to find debug symbols in the current call stack"); + return false; + } + + return true; + } + bool DoExecute(Args &args, CommandReturnObject &result) override { Target *target = m_exe_ctx.GetTargetPtr(); result.SetStatus(eReturnStatusFailed); @@ -4150,100 +4320,22 @@ protected: const bool file_option_set = m_file_option.GetOptionValue().OptionWasSet(); const bool frame_option_set = m_current_frame_option.GetOptionValue().OptionWasSet(); + const bool stack_option_set = + m_current_stack_option.GetOptionValue().OptionWasSet(); const size_t argc = args.GetArgumentCount(); if (argc == 0) { - if (uuid_option_set || file_option_set || frame_option_set) { - bool success = false; - bool error_set = false; - if (frame_option_set) { - Process *process = m_exe_ctx.GetProcessPtr(); - if (process) { - const StateType process_state = process->GetState(); - if (StateIsStoppedState(process_state, true)) { - StackFrame *frame = m_exe_ctx.GetFramePtr(); - if (frame) { - ModuleSP frame_module_sp( - frame->GetSymbolContext(eSymbolContextModule).module_sp); - if (frame_module_sp) { - if (FileSystem::Instance().Exists( - frame_module_sp->GetPlatformFileSpec())) { - module_spec.GetArchitecture() = - frame_module_sp->GetArchitecture(); - module_spec.GetFileSpec() = - frame_module_sp->GetPlatformFileSpec(); - } - module_spec.GetUUID() = frame_module_sp->GetUUID(); - success = module_spec.GetUUID().IsValid() || - module_spec.GetFileSpec(); - } else { - result.AppendError("frame has no module"); - error_set = true; - } - } else { - result.AppendError("invalid current frame"); - error_set = true; - } - } else { - result.AppendErrorWithFormat("process is not stopped: %s", - StateAsCString(process_state)); - error_set = true; - } - } else { - result.AppendError( - "a process must exist in order to use the --frame option"); - error_set = true; - } - } else { - if (uuid_option_set) { - module_spec.GetUUID() = - m_uuid_option_group.GetOptionValue().GetCurrentValue(); - success |= module_spec.GetUUID().IsValid(); - } else if (file_option_set) { - module_spec.GetFileSpec() = - m_file_option.GetOptionValue().GetCurrentValue(); - ModuleSP module_sp( - target->GetImages().FindFirstModule(module_spec)); - if (module_sp) { - module_spec.GetFileSpec() = module_sp->GetFileSpec(); - module_spec.GetPlatformFileSpec() = - module_sp->GetPlatformFileSpec(); - module_spec.GetUUID() = module_sp->GetUUID(); - module_spec.GetArchitecture() = module_sp->GetArchitecture(); - } else { - module_spec.GetArchitecture() = target->GetArchitecture(); - } - success |= module_spec.GetUUID().IsValid() || - FileSystem::Instance().Exists(module_spec.GetFileSpec()); - } - } - - if (success) { - if (Symbols::DownloadObjectAndSymbolFile(module_spec)) { - if (module_spec.GetSymbolFileSpec()) - success = AddModuleSymbols(target, module_spec, flush, result); - } - } - - if (!success && !error_set) { - StreamString error_strm; - if (uuid_option_set) { - error_strm.PutCString("unable to find debug symbols for UUID "); - module_spec.GetUUID().Dump(&error_strm); - } else if (file_option_set) { - error_strm.PutCString( - "unable to find debug symbols for the executable file "); - error_strm << module_spec.GetFileSpec(); - } else if (frame_option_set) { - error_strm.PutCString( - "unable to find debug symbols for the current frame"); - } - result.AppendError(error_strm.GetString()); - } - } else { + if (uuid_option_set) + AddSymbolsForUUID(result, flush); + else if (file_option_set) + AddSymbolsForFile(result, flush); + else if (frame_option_set) + AddSymbolsForFrame(result, flush); + else if (stack_option_set) + AddSymbolsForStack(result, flush); + else result.AppendError("one or more symbol file paths must be specified, " "or options must be specified"); - } } else { if (uuid_option_set) { result.AppendError("specify either one or more paths to symbol files " @@ -4310,6 +4402,7 @@ protected: OptionGroupUUID m_uuid_option_group; OptionGroupFile m_file_option; OptionGroupBoolean m_current_frame_option; + OptionGroupBoolean m_current_stack_option; }; #pragma mark CommandObjectTargetSymbols @@ -4511,29 +4604,29 @@ public: Command Based stop-hooks: ------------------------- Stop hooks can run a list of lldb commands by providing one or more - --one-line-command options. The commands will get run in the order they are + --one-line-command options. The commands will get run in the order they are added. Or you can provide no commands, in which case you will enter a command editor where you can enter the commands to be run. - + Python Based Stop Hooks: ------------------------ Stop hooks can be implemented with a suitably defined Python class, whose name is passed in the --python-class option. - + When the stop hook is added, the class is initialized by calling: - + def __init__(self, target, extra_args, internal_dict): - + target: The target that the stop hook is being added to. - extra_args: An SBStructuredData Dictionary filled with the -key -value - option pairs passed to the command. + extra_args: An SBStructuredData Dictionary filled with the -key -value + option pairs passed to the command. dict: An implementation detail provided by lldb. - Then when the stop-hook triggers, lldb will run the 'handle_stop' method. + Then when the stop-hook triggers, lldb will run the 'handle_stop' method. The method has the signature: - + def handle_stop(self, exe_ctx, stream): - + exe_ctx: An SBExecutionContext for the thread that has stopped. stream: An SBStream, anything written to this stream will be printed in the the stop message when the process stops. @@ -4542,12 +4635,12 @@ Python Based Stop Hooks: from all the stop hook executions on threads that stopped with a reason, then the process will continue. Note that this will happen only after all the stop hooks are run. - + Filter Options: --------------- Stop hooks can be set to always run, or to only run when the stopped thread matches the filter options passed on the command line. The available filter - options include a shared library or a thread or queue specification, + options include a shared library or a thread or queue specification, a line range in a source file, a function name or a class name. )"); m_all_options.Append(&m_python_class_options, @@ -4896,6 +4989,55 @@ public: ~CommandObjectMultiwordTargetStopHooks() override = default; }; +#pragma mark CommandObjectTargetDumpTypesystem + +/// Dumps the TypeSystem of the selected Target. +class CommandObjectTargetDumpTypesystem : public CommandObjectParsed { +public: + CommandObjectTargetDumpTypesystem(CommandInterpreter &interpreter) + : CommandObjectParsed( + interpreter, "target dump typesystem", + "Dump the state of the target's internal type system.\n" + "Intended to be used for debugging LLDB itself.", + nullptr, eCommandRequiresTarget) {} + + ~CommandObjectTargetDumpTypesystem() override = default; + +protected: + bool DoExecute(Args &command, CommandReturnObject &result) override { + if (!command.empty()) { + result.AppendError("target dump typesystem doesn't take arguments."); + return result.Succeeded(); + } + + // Go over every scratch TypeSystem and dump to the command output. + for (TypeSystem *ts : GetSelectedTarget().GetScratchTypeSystems()) + ts->Dump(result.GetOutputStream().AsRawOstream()); + + result.SetStatus(eReturnStatusSuccessFinishResult); + return result.Succeeded(); + } +}; + +#pragma mark CommandObjectTargetDump + +/// Multi-word command for 'target dump'. +class CommandObjectTargetDump : public CommandObjectMultiword { +public: + // Constructors and Destructors + CommandObjectTargetDump(CommandInterpreter &interpreter) + : CommandObjectMultiword( + interpreter, "target dump", + "Commands for dumping information about the target.", + "target dump [typesystem]") { + LoadSubCommand( + "typesystem", + CommandObjectSP(new CommandObjectTargetDumpTypesystem(interpreter))); + } + + ~CommandObjectTargetDump() override = default; +}; + #pragma mark CommandObjectMultiwordTarget // CommandObjectMultiwordTarget @@ -4909,6 +5051,8 @@ CommandObjectMultiwordTarget::CommandObjectMultiwordTarget( CommandObjectSP(new CommandObjectTargetCreate(interpreter))); LoadSubCommand("delete", CommandObjectSP(new CommandObjectTargetDelete(interpreter))); + LoadSubCommand("dump", + CommandObjectSP(new CommandObjectTargetDump(interpreter))); LoadSubCommand("list", CommandObjectSP(new CommandObjectTargetList(interpreter))); LoadSubCommand("select", diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectThread.cpp b/contrib/llvm-project/lldb/source/Commands/CommandObjectThread.cpp index 7247601b292b..71e67f6ba208 100644 --- a/contrib/llvm-project/lldb/source/Commands/CommandObjectThread.cpp +++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectThread.cpp @@ -292,16 +292,10 @@ public: // Check if we are in Non-Stop mode TargetSP target_sp = execution_context ? execution_context->GetTargetSP() : TargetSP(); - if (target_sp && target_sp->GetNonStopModeEnabled()) { - // NonStopMode runs all threads by definition, so when it is on we don't - // need to check the process setting for runs all threads. - m_run_mode = eOnlyThisThread; - } else { - ProcessSP process_sp = - execution_context ? execution_context->GetProcessSP() : ProcessSP(); - if (process_sp && process_sp->GetSteppingRunsAllThreads()) - m_run_mode = eAllThreads; - } + ProcessSP process_sp = + execution_context ? execution_context->GetProcessSP() : ProcessSP(); + if (process_sp && process_sp->GetSteppingRunsAllThreads()) + m_run_mode = eAllThreads; m_avoid_regexp.clear(); m_step_in_target.clear(); @@ -532,12 +526,12 @@ protected: return false; } - // If we got a new plan, then set it to be a master plan (User level Plans - // should be master plans so that they can be interruptible). Then resume - // the process. + // If we got a new plan, then set it to be a controlling plan (User level + // Plans should be controlling plans so that they can be interruptible). + // Then resume the process. if (new_plan_sp) { - new_plan_sp->SetIsMasterPlan(true); + new_plan_sp->SetIsControllingPlan(true); new_plan_sp->SetOkayToDiscard(false); if (m_options.m_step_count > 1) { @@ -1027,11 +1021,12 @@ protected: abort_other_plans, &address_list.front(), address_list.size(), m_options.m_stop_others, m_options.m_frame_idx, new_plan_status); if (new_plan_sp) { - // User level plans should be master plans so they can be interrupted + // User level plans should be controlling plans so they can be + // interrupted // (e.g. by hitting a breakpoint) and other plans executed by the // user (stepping around the breakpoint) and then a "continue" will // resume the original plan. - new_plan_sp->SetIsMasterPlan(true); + new_plan_sp->SetIsControllingPlan(true); new_plan_sp->SetOkayToDiscard(false); } else { result.SetError(new_plan_status); @@ -1935,15 +1930,14 @@ public: "process to different formats.", "thread trace export <export-plugin> [<subcommand objects>]") { - for (uint32_t i = 0; true; i++) { - if (const char *plugin_name = - PluginManager::GetTraceExporterPluginNameAtIndex(i)) { - if (ThreadTraceExportCommandCreator command_creator = - PluginManager::GetThreadTraceExportCommandCreatorAtIndex(i)) { - LoadSubCommand(plugin_name, command_creator(interpreter)); - } - } else { - break; + unsigned i = 0; + for (llvm::StringRef plugin_name = + PluginManager::GetTraceExporterPluginNameAtIndex(i++); + !plugin_name.empty(); + plugin_name = PluginManager::GetTraceExporterPluginNameAtIndex(i++)) { + if (ThreadTraceExportCommandCreator command_creator = + PluginManager::GetThreadTraceExportCommandCreatorAtIndex(i)) { + LoadSubCommand(plugin_name, command_creator(interpreter)); } } } @@ -2205,9 +2199,8 @@ public: bool DoExecute(Args &command, CommandReturnObject &result) override { Target &target = m_exe_ctx.GetTargetRef(); - result.GetOutputStream().Printf( - "Trace technology: %s\n", - target.GetTrace()->GetPluginName().AsCString()); + result.GetOutputStream().Format("Trace technology: {0}\n", + target.GetTrace()->GetPluginName()); return CommandObjectIterateOverThreads::DoExecute(command, result); } diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectTrace.cpp b/contrib/llvm-project/lldb/source/Commands/CommandObjectTrace.cpp index c55fed45d4f4..62ee48ca0546 100644 --- a/contrib/llvm-project/lldb/source/Commands/CommandObjectTrace.cpp +++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectTrace.cpp @@ -117,8 +117,8 @@ protected: json_file.GetDirectory().AsCString())) { lldb::TraceSP trace_sp = traceOrErr.get(); if (m_options.m_verbose && trace_sp) - result.AppendMessageWithFormat("loading trace with plugin %s\n", - trace_sp->GetPluginName().AsCString()); + result.AppendMessageWithFormatv("loading trace with plugin {0}\n", + trace_sp->GetPluginName()); } else return end_with_failure(traceOrErr.takeError()); diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectType.cpp b/contrib/llvm-project/lldb/source/Commands/CommandObjectType.cpp index 90e224867e2a..0562b6be3cb5 100644 --- a/contrib/llvm-project/lldb/source/Commands/CommandObjectType.cpp +++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectType.cpp @@ -1598,7 +1598,7 @@ static bool FixArrayTypeNameWithRegex(ConstString &type_name) { std::string type_name_str(type_name.GetCString()); type_name_str.resize(type_name_str.length() - 2); if (type_name_str.back() != ' ') - type_name_str.append(" \\[[0-9]+\\]"); + type_name_str.append(" ?\\[[0-9]+\\]"); else type_name_str.append("\\[[0-9]+\\]"); type_name.SetCString(type_name_str.c_str()); @@ -2978,7 +2978,7 @@ public: CommandObjectTypeFilter(CommandInterpreter &interpreter) : CommandObjectMultiword(interpreter, "type filter", "Commands for operating on type filters.", - "type synthetic [<sub-command-options>] ") { + "type filter [<sub-command-options>] ") { LoadSubCommand( "add", CommandObjectSP(new CommandObjectTypeFilterAdd(interpreter))); LoadSubCommand("clear", CommandObjectSP( diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectWatchpoint.cpp b/contrib/llvm-project/lldb/source/Commands/CommandObjectWatchpoint.cpp index d7a446fc366c..9fbf036a19d1 100644 --- a/contrib/llvm-project/lldb/source/Commands/CommandObjectWatchpoint.cpp +++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectWatchpoint.cpp @@ -56,7 +56,7 @@ static int32_t WithRSAIndex(llvm::StringRef Arg) { uint32_t i; for (i = 0; i < 4; ++i) - if (Arg.find(RSA[i]) != llvm::StringRef::npos) + if (Arg.contains(RSA[i])) return i; return -1; } diff --git a/contrib/llvm-project/lldb/source/Commands/Options.td b/contrib/llvm-project/lldb/source/Commands/Options.td index 6abb4788bed0..3e89eb0f6bda 100644 --- a/contrib/llvm-project/lldb/source/Commands/Options.td +++ b/contrib/llvm-project/lldb/source/Commands/Options.td @@ -73,7 +73,7 @@ let Command = "breakpoint modify" in { "index matches this argument.">; def breakpoint_modify_thread_id : Option<"thread-id", "t">, Group<1>, Arg<"ThreadID">, Desc<"The breakpoint stops only for the thread whose TID " - "matches this argument.">; + "matches this argument. The token 'current' resolves to the current thread's ID.">; def breakpoint_modify_thread_name : Option<"thread-name", "T">, Group<1>, Arg<"ThreadName">, Desc<"The breakpoint stops only for the thread whose " "thread name matches this argument.">; @@ -151,10 +151,10 @@ let Command = "breakpoint set" in { def breakpoint_set_selector : Option<"selector", "S">, Group<5>, Arg<"Selector">, Required, Desc<"Set the breakpoint by ObjC selector name. Can be repeated multiple " - "times tomake one breakpoint for multiple Selectors.">; + "times to make one breakpoint for multiple Selectors.">; def breakpoint_set_method : Option<"method", "M">, Group<6>, Arg<"Method">, Required, Desc<"Set the breakpoint by C++ method names. Can be repeated " - "multiple times tomake one breakpoint for multiple methods.">; + "multiple times to make one breakpoint for multiple methods.">; def breakpoint_set_func_regex : Option<"func-regex", "r">, Group<7>, Arg<"RegularExpression">, Required, Desc<"Set the breakpoint by function " "name, evaluating a regular-expression to find the function name(s).">; @@ -355,7 +355,7 @@ let Command = "expression" in { Desc<"When specified, debug the JIT code by setting a breakpoint on the " "first instruction and forcing breakpoints to not be ignored (-i0) and no " "unwinding to happen on error (-u0).">; - def expression_options_language : Option<"language", "l">, Groups<[1,2]>, + def expression_options_language : Option<"language", "l">, Groups<[1,2,3]>, Arg<"Language">, Desc<"Specifies the Language to use when parsing the " "expression. If not set the target.language setting is used.">; def expression_options_apply_fixits : Option<"apply-fixits", "X">, @@ -404,6 +404,13 @@ let Command = "frame recognizer add" in { Desc<"Give the name of a Python class to use for this frame recognizer.">; def frame_recognizer_regex : Option<"regex", "x">, Desc<"Function name and module name are actually regular expressions.">; + def frame_recognizer_first_instruction_only : Option<"first-instruction-only", "f">, Arg<"Boolean">, + Desc<"If true, only apply this recognizer to frames whose PC currently points to the " + "first instruction of the specified function. If false, the recognizer " + "will always be applied, regardless of the current position within the specified function. The " + "implementor should keep in mind that some features, e.g. accessing function argument " + "values via $arg<N>, are not guaranteed to work reliably in this case, so extra care must " + "be taken to make the recognizer operate correctly. Defaults to true.">; } let Command = "history" in { @@ -529,6 +536,10 @@ let Command = "source" in { Desc<"If true, stop executing commands on continue.">; def source_silent_run : Option<"silent-run", "s">, Arg<"Boolean">, Desc<"If true don't echo commands while executing.">; + def cmd_relative_to_command_file : Option<"relative-to-command-file", "C">, + Desc<"Resolve non-absolute paths relative to the location of the " + "current command file. This argument can only be used when the command is " + "being sourced from a file.">; } let Command = "alias" in { @@ -742,6 +753,17 @@ let Command = "process save_core" in { def process_save_core_style : Option<"style", "s">, Group<1>, EnumArg<"SaveCoreStyle", "SaveCoreStyles()">, Desc<"Request a specific style " "of corefile to be saved.">; + def process_save_core_plugin_name : Option<"plugin-name", "p">, + OptionalArg<"Plugin">, Desc<"Specify a plugin name to create the core file." + "This allows core files to be saved in different formats.">; +} + +let Command = "process trace save" in { + def process_trace_save_directory: Option<"directory", "d">, + Group<1>, + Arg<"Value">, Required, + Desc<"The directory where the trace will be saved." + "It will be created if it does not exist.">; } let Command = "script import" in { @@ -765,12 +787,23 @@ let Command = "script add" in { Desc<"Name of the Python class to bind to this command name.">; def script_add_help : Option<"help", "h">, Group<1>, Arg<"HelpText">, Desc<"The help text to display for this command.">; + def script_add_overwrite : Option<"overwrite", "o">, Groups<[1,2]>, + Desc<"Overwrite an existing command at this node.">; def script_add_synchronicity : Option<"synchronicity", "s">, EnumArg<"ScriptedCommandSynchronicity", "ScriptSynchroType()">, Desc<"Set the synchronicity of this command's executions with regard to " "LLDB event system.">; } +let Command = "container add" in { + def container_add_help : Option<"help", "h">, Arg<"HelpText">, + Desc<"Help text for this command">; + def container_add_long_help : Option<"long-help", "H">, Arg<"HelpText">, + Desc<"Long help text for this command">; + def container_add_overwrite : Option<"overwrite", "o">, Group<1>, + Desc<"Overwrite an existing command at this node.">; +} + let Command = "script" in { def script_language : Option<"language", "l">, EnumArg<"ScriptLang", "ScriptOptionEnum()">, Desc<"Specify the scripting " @@ -1272,3 +1305,8 @@ let Command = "trace schema" in { def trace_schema_verbose : Option<"verbose", "v">, Group<1>, Desc<"Show verbose trace schema logging for debugging the plug-in.">; } + +let Command = "statistics dump" in { + def statistics_dump_all: Option<"all-targets", "a">, Group<1>, + Desc<"Include statistics for all targets.">; +} diff --git a/contrib/llvm-project/lldb/source/Core/Address.cpp b/contrib/llvm-project/lldb/source/Core/Address.cpp index f0c7e2b34f99..122bed924b42 100644 --- a/contrib/llvm-project/lldb/source/Core/Address.cpp +++ b/contrib/llvm-project/lldb/source/Core/Address.cpp @@ -389,6 +389,19 @@ bool Address::SetOpcodeLoadAddress(lldb::addr_t load_addr, Target *target, return false; } +bool Address::GetDescription(Stream &s, Target &target, + DescriptionLevel level) const { + assert(level == eDescriptionLevelBrief && + "Non-brief descriptions not implemented"); + LineEntry line_entry; + if (CalculateSymbolContextLineEntry(line_entry)) { + s.Printf(" (%s:%u:%u)", line_entry.file.GetFilename().GetCString(), + line_entry.line, line_entry.column); + return true; + } + return false; +} + bool Address::Dump(Stream *s, ExecutionContextScope *exe_scope, DumpStyle style, DumpStyle fallback_style, uint32_t addr_size) const { // If the section was nullptr, only load address is going to work unless we diff --git a/contrib/llvm-project/lldb/source/Core/AddressRange.cpp b/contrib/llvm-project/lldb/source/Core/AddressRange.cpp index af6e31a67da3..66dcda574890 100644 --- a/contrib/llvm-project/lldb/source/Core/AddressRange.cpp +++ b/contrib/llvm-project/lldb/source/Core/AddressRange.cpp @@ -59,15 +59,6 @@ bool AddressRange::Contains(const Address &addr) const { return ContainsFileAddress(addr); } -// -// bool -// AddressRange::Contains (const Address *addr) const -//{ -// if (addr) -// return Contains (*addr); -// return false; -//} - bool AddressRange::ContainsFileAddress(const Address &addr) const { if (addr.GetSection() == m_base_addr.GetSection()) return (addr.GetOffset() - m_base_addr.GetOffset()) < GetByteSize(); @@ -212,11 +203,3 @@ void AddressRange::DumpDebug(Stream *s) const { static_cast<void *>(m_base_addr.GetSection().get()), m_base_addr.GetOffset(), GetByteSize()); } -// -// bool -// lldb::operator== (const AddressRange& lhs, const AddressRange& rhs) -//{ -// if (lhs.GetBaseAddress() == rhs.GetBaseAddress()) -// return lhs.GetByteSize() == rhs.GetByteSize(); -// return false; -//} diff --git a/contrib/llvm-project/lldb/source/Core/Communication.cpp b/contrib/llvm-project/lldb/source/Core/Communication.cpp index 5640e0510cf1..0ad2751f24f0 100644 --- a/contrib/llvm-project/lldb/source/Core/Communication.cpp +++ b/contrib/llvm-project/lldb/source/Core/Communication.cpp @@ -176,8 +176,8 @@ size_t Communication::Write(const void *src, size_t src_len, std::lock_guard<std::mutex> guard(m_write_mutex); LLDB_LOG(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_COMMUNICATION), - "{0} Communication::Write (src = {1}, src_len = %" PRIu64 - ") connection = {2}", + "{0} Communication::Write (src = {1}, src_len = {2}" + ") connection = {3}", this, src, (uint64_t)src_len, connection_sp.get()); if (connection_sp) @@ -189,6 +189,16 @@ size_t Communication::Write(const void *src, size_t src_len, return 0; } +size_t Communication::WriteAll(const void *src, size_t src_len, + ConnectionStatus &status, Status *error_ptr) { + size_t total_written = 0; + do + total_written += Write(static_cast<const char *>(src) + total_written, + src_len - total_written, status, error_ptr); + while (status == eConnectionStatusSuccess && total_written < src_len); + return total_written; +} + bool Communication::StartReadThread(Status *error_ptr) { if (error_ptr) error_ptr->Clear(); diff --git a/contrib/llvm-project/lldb/source/Core/Debugger.cpp b/contrib/llvm-project/lldb/source/Core/Debugger.cpp index 17c3ba426f71..32dcfb1ce17b 100644 --- a/contrib/llvm-project/lldb/source/Core/Debugger.cpp +++ b/contrib/llvm-project/lldb/source/Core/Debugger.cpp @@ -488,7 +488,7 @@ void Debugger::Terminate() { "Debugger::Terminate called without a matching Debugger::Initialize!"); if (g_debugger_list_ptr && g_debugger_list_mutex_ptr) { - // Clear our master list of debugger objects + // Clear our global list of debugger objects { std::lock_guard<std::recursive_mutex> guard(*g_debugger_list_mutex_ptr); for (const auto &debugger : *g_debugger_list_ptr) @@ -723,10 +723,10 @@ Debugger::Debugger(lldb::LogOutputCallback log_callback, void *baton) m_collection_sp->AppendProperty( ConstString("target"), ConstString("Settings specify to debugging targets."), true, - Target::GetGlobalProperties()->GetValueProperties()); + Target::GetGlobalProperties().GetValueProperties()); m_collection_sp->AppendProperty( ConstString("platform"), ConstString("Platform settings."), true, - Platform::GetGlobalPlatformProperties()->GetValueProperties()); + Platform::GetGlobalPlatformProperties().GetValueProperties()); m_collection_sp->AppendProperty( ConstString("symbols"), ConstString("Symbol lookup and cache settings."), true, ModuleList::GetGlobalModuleListProperties().GetValueProperties()); @@ -1243,7 +1243,7 @@ bool Debugger::EnableLog(llvm::StringRef channel, log_stream_sp = pos->second.lock(); if (!log_stream_sp) { File::OpenOptions flags = - File::eOpenOptionWrite | File::eOpenOptionCanCreate; + File::eOpenOptionWriteOnly | File::eOpenOptionCanCreate; if (log_options & LLDB_LOG_OPTION_APPEND) flags |= File::eOpenOptionAppend; else @@ -1423,10 +1423,9 @@ void Debugger::HandleProcessEvent(const EventSP &event_sp) { output_stream_sp->PutCString(content_stream.GetString()); } } else { - error_stream_sp->Printf("Failed to print structured " - "data with plugin %s: %s", - plugin_sp->GetPluginName().AsCString(), - error.AsCString()); + error_stream_sp->Format("Failed to print structured " + "data with plugin {0}: {1}", + plugin_sp->GetPluginName(), error); } } } diff --git a/contrib/llvm-project/lldb/source/Core/Disassembler.cpp b/contrib/llvm-project/lldb/source/Core/Disassembler.cpp index 704b3df4b2ac..00d92053bc4f 100644 --- a/contrib/llvm-project/lldb/source/Core/Disassembler.cpp +++ b/contrib/llvm-project/lldb/source/Core/Disassembler.cpp @@ -64,9 +64,8 @@ DisassemblerSP Disassembler::FindPlugin(const ArchSpec &arch, DisassemblerCreateInstance create_callback = nullptr; if (plugin_name) { - ConstString const_plugin_name(plugin_name); - create_callback = PluginManager::GetDisassemblerCreateCallbackForPluginName( - const_plugin_name); + create_callback = + PluginManager::GetDisassemblerCreateCallbackForPluginName(plugin_name); if (create_callback) { DisassemblerSP disassembler_sp(create_callback(arch, flavor)); @@ -1123,6 +1122,10 @@ bool PseudoInstruction::HasDelaySlot() { return false; } +bool PseudoInstruction::IsLoad() { return false; } + +bool PseudoInstruction::IsAuthenticated() { return false; } + size_t PseudoInstruction::Decode(const lldb_private::Disassembler &disassembler, const lldb_private::DataExtractor &data, lldb::offset_t data_offset) { diff --git a/contrib/llvm-project/lldb/source/Core/DynamicLoader.cpp b/contrib/llvm-project/lldb/source/Core/DynamicLoader.cpp index 10d2b7207018..1c7b9125e4d1 100644 --- a/contrib/llvm-project/lldb/source/Core/DynamicLoader.cpp +++ b/contrib/llvm-project/lldb/source/Core/DynamicLoader.cpp @@ -30,13 +30,11 @@ using namespace lldb; using namespace lldb_private; DynamicLoader *DynamicLoader::FindPlugin(Process *process, - const char *plugin_name) { + llvm::StringRef plugin_name) { DynamicLoaderCreateInstance create_callback = nullptr; - if (plugin_name) { - ConstString const_plugin_name(plugin_name); + if (!plugin_name.empty()) { create_callback = - PluginManager::GetDynamicLoaderCreateCallbackForPluginName( - const_plugin_name); + PluginManager::GetDynamicLoaderCreateCallbackForPluginName(plugin_name); if (create_callback) { std::unique_ptr<DynamicLoader> instance_up( create_callback(process, true)); diff --git a/contrib/llvm-project/lldb/source/Core/EmulateInstruction.cpp b/contrib/llvm-project/lldb/source/Core/EmulateInstruction.cpp index 9b9111408209..c352b0129382 100644 --- a/contrib/llvm-project/lldb/source/Core/EmulateInstruction.cpp +++ b/contrib/llvm-project/lldb/source/Core/EmulateInstruction.cpp @@ -46,10 +46,9 @@ EmulateInstruction::FindPlugin(const ArchSpec &arch, const char *plugin_name) { EmulateInstructionCreateInstance create_callback = nullptr; if (plugin_name) { - ConstString const_plugin_name(plugin_name); create_callback = PluginManager::GetEmulateInstructionCreateCallbackForPluginName( - const_plugin_name); + plugin_name); if (create_callback) { EmulateInstruction *emulate_insn_ptr = create_callback(arch, supported_inst_type); diff --git a/contrib/llvm-project/lldb/source/Core/IOHandler.cpp b/contrib/llvm-project/lldb/source/Core/IOHandler.cpp index c6f05d43a2a7..c35b17990842 100644 --- a/contrib/llvm-project/lldb/source/Core/IOHandler.cpp +++ b/contrib/llvm-project/lldb/source/Core/IOHandler.cpp @@ -251,8 +251,7 @@ IOHandlerEditline::IOHandlerEditline( m_delegate(delegate), m_prompt(), m_continuation_prompt(), m_current_lines_ptr(nullptr), m_base_line_number(line_number_start), m_curr_line_idx(UINT32_MAX), m_multi_line(multi_line), - m_color_prompts(color_prompts), m_interrupt_exits(true), - m_editing(false) { + m_color_prompts(color_prompts), m_interrupt_exits(true) { SetPrompt(prompt); #if LLDB_ENABLE_LIBEDIT @@ -399,7 +398,6 @@ bool IOHandlerEditline::GetLine(std::string &line, bool &interrupted) { } if (!got_line && in) { - m_editing = true; while (!got_line) { char *r = fgets(buffer, sizeof(buffer), in); #ifdef _WIN32 @@ -425,7 +423,6 @@ bool IOHandlerEditline::GetLine(std::string &line, bool &interrupted) { m_line_buffer += buffer; got_line = SplitLine(m_line_buffer); } - m_editing = false; } if (got_line) { diff --git a/contrib/llvm-project/lldb/source/Core/IOHandlerCursesGUI.cpp b/contrib/llvm-project/lldb/source/Core/IOHandlerCursesGUI.cpp index 4bed788d4863..9122117ef5ff 100644 --- a/contrib/llvm-project/lldb/source/Core/IOHandlerCursesGUI.cpp +++ b/contrib/llvm-project/lldb/source/Core/IOHandlerCursesGUI.cpp @@ -36,6 +36,7 @@ #include "lldb/Interpreter/CommandCompletions.h" #include "lldb/Interpreter/CommandInterpreter.h" +#include "lldb/Interpreter/OptionGroupPlatform.h" #if LLDB_ENABLE_CURSES #include "lldb/Breakpoint/BreakpointLocation.h" @@ -44,6 +45,7 @@ #include "lldb/Core/ValueObject.h" #include "lldb/Core/ValueObjectRegister.h" #include "lldb/Symbol/Block.h" +#include "lldb/Symbol/CompileUnit.h" #include "lldb/Symbol/Function.h" #include "lldb/Symbol/Symbol.h" #include "lldb/Symbol/VariableList.h" @@ -83,10 +85,15 @@ using llvm::StringRef; // we may want curses to be disabled for some builds for instance, windows #if LLDB_ENABLE_CURSES +#define KEY_CTRL_A 1 +#define KEY_CTRL_E 5 +#define KEY_CTRL_K 11 #define KEY_RETURN 10 #define KEY_ESCAPE 27 +#define KEY_DELETE 127 #define KEY_SHIFT_TAB (KEY_MAX + 1) +#define KEY_ALT_ENTER (KEY_MAX + 2) namespace curses { class Menu; @@ -342,15 +349,30 @@ protected: // A surface is an abstraction for something than can be drawn on. The surface // have a width, a height, a cursor position, and a multitude of drawing // operations. This type should be sub-classed to get an actually useful ncurses -// object, such as a Window, SubWindow, Pad, or a SubPad. +// object, such as a Window or a Pad. class Surface { public: - Surface() : m_window(nullptr) {} + enum class Type { Window, Pad }; + + Surface(Surface::Type type) : m_type(type), m_window(nullptr) {} WINDOW *get() { return m_window; } operator WINDOW *() { return m_window; } + Surface SubSurface(Rect bounds) { + Surface subSurface(m_type); + if (m_type == Type::Pad) + subSurface.m_window = + ::subpad(m_window, bounds.size.height, bounds.size.width, + bounds.origin.y, bounds.origin.x); + else + subSurface.m_window = + ::derwin(m_window, bounds.size.height, bounds.size.width, + bounds.origin.y, bounds.origin.x); + return subSurface; + } + // Copy a region of the surface to another surface. void CopyToSurface(Surface &target, Point source_origin, Point target_origin, Size size) { @@ -534,41 +556,32 @@ public: } protected: + Type m_type; WINDOW *m_window; }; class Pad : public Surface { public: - Pad(Size size) { m_window = ::newpad(size.height, size.width); } - - ~Pad() { ::delwin(m_window); } -}; - -class SubPad : public Surface { -public: - SubPad(Pad &pad, Rect bounds) { - m_window = ::subpad(pad.get(), bounds.size.height, bounds.size.width, - bounds.origin.y, bounds.origin.x); - } - SubPad(SubPad &subpad, Rect bounds) { - m_window = ::subpad(subpad.get(), bounds.size.height, bounds.size.width, - bounds.origin.y, bounds.origin.x); + Pad(Size size) : Surface(Surface::Type::Pad) { + m_window = ::newpad(size.height, size.width); } - ~SubPad() { ::delwin(m_window); } + ~Pad() { ::delwin(m_window); } }; class Window : public Surface { public: Window(const char *name) - : m_name(name), m_panel(nullptr), m_parent(nullptr), m_subwindows(), - m_delegate_sp(), m_curr_active_window_idx(UINT32_MAX), + : Surface(Surface::Type::Window), m_name(name), m_panel(nullptr), + m_parent(nullptr), m_subwindows(), m_delegate_sp(), + m_curr_active_window_idx(UINT32_MAX), m_prev_active_window_idx(UINT32_MAX), m_delete(false), m_needs_update(true), m_can_activate(true), m_is_subwin(false) {} Window(const char *name, WINDOW *w, bool del = true) - : m_name(name), m_panel(nullptr), m_parent(nullptr), m_subwindows(), - m_delegate_sp(), m_curr_active_window_idx(UINT32_MAX), + : Surface(Surface::Type::Window), m_name(name), m_panel(nullptr), + m_parent(nullptr), m_subwindows(), m_delegate_sp(), + m_curr_active_window_idx(UINT32_MAX), m_prev_active_window_idx(UINT32_MAX), m_delete(del), m_needs_update(true), m_can_activate(true), m_is_subwin(false) { if (w) @@ -576,8 +589,8 @@ public: } Window(const char *name, const Rect &bounds) - : m_name(name), m_parent(nullptr), m_subwindows(), m_delegate_sp(), - m_curr_active_window_idx(UINT32_MAX), + : Surface(Surface::Type::Window), m_name(name), m_parent(nullptr), + m_subwindows(), m_delegate_sp(), m_curr_active_window_idx(UINT32_MAX), m_prev_active_window_idx(UINT32_MAX), m_delete(true), m_needs_update(true), m_can_activate(true), m_is_subwin(false) { Reset(::newwin(bounds.size.height, bounds.size.width, bounds.origin.y, @@ -969,20 +982,6 @@ private: const Window &operator=(const Window &) = delete; }; -class DerivedWindow : public Surface { -public: - DerivedWindow(Window &window, Rect bounds) { - m_window = ::derwin(window.get(), bounds.size.height, bounds.size.width, - bounds.origin.y, bounds.origin.x); - } - DerivedWindow(DerivedWindow &derived_window, Rect bounds) { - m_window = ::derwin(derived_window.get(), bounds.size.height, - bounds.size.width, bounds.origin.y, bounds.origin.x); - } - - ~DerivedWindow() { ::delwin(m_window); } -}; - ///////// // Forms ///////// @@ -1024,7 +1023,7 @@ public: // Draw the field in the given subpad surface. The surface have a height that // is equal to the height returned by FieldDelegateGetHeight(). If the field // is selected in the form window, then is_selected will be true. - virtual void FieldDelegateDraw(SubPad &surface, bool is_selected) = 0; + virtual void FieldDelegateDraw(Surface &surface, bool is_selected) = 0; // Handle the key that wasn't handled by the form window or a container field. virtual HandleCharResult FieldDelegateHandleChar(int key) { @@ -1111,11 +1110,12 @@ public: int GetContentLength() { return m_content.length(); } - void DrawContent(SubPad &surface, bool is_selected) { + void DrawContent(Surface &surface, bool is_selected) { + UpdateScrolling(surface.GetWidth()); + surface.MoveCursor(0, 0); const char *text = m_content.c_str() + m_first_visibile_char; surface.PutCString(text, surface.GetWidth()); - m_last_drawn_content_width = surface.GetWidth(); // Highlight the cursor. surface.MoveCursor(GetCursorXPosition(), 0); @@ -1130,17 +1130,17 @@ public: surface.AttributeOff(A_REVERSE); } - void DrawField(SubPad &surface, bool is_selected) { + void DrawField(Surface &surface, bool is_selected) { surface.TitledBox(m_label.c_str()); Rect content_bounds = surface.GetFrame(); content_bounds.Inset(1, 1); - SubPad content_surface = SubPad(surface, content_bounds); + Surface content_surface = surface.SubSurface(content_bounds); DrawContent(content_surface, is_selected); } - void DrawError(SubPad &surface) { + void DrawError(Surface &surface) { if (!FieldDelegateHasError()) return; surface.MoveCursor(0, 0); @@ -1151,17 +1151,33 @@ public: surface.AttributeOff(COLOR_PAIR(RedOnBlack)); } - void FieldDelegateDraw(SubPad &surface, bool is_selected) override { + void FieldDelegateDraw(Surface &surface, bool is_selected) override { Rect frame = surface.GetFrame(); Rect field_bounds, error_bounds; frame.HorizontalSplit(GetFieldHeight(), field_bounds, error_bounds); - SubPad field_surface = SubPad(surface, field_bounds); - SubPad error_surface = SubPad(surface, error_bounds); + Surface field_surface = surface.SubSurface(field_bounds); + Surface error_surface = surface.SubSurface(error_bounds); DrawField(field_surface, is_selected); DrawError(error_surface); } + // Get the position of the last visible character. + int GetLastVisibleCharPosition(int width) { + int position = m_first_visibile_char + width - 1; + return std::min(position, GetContentLength()); + } + + void UpdateScrolling(int width) { + if (m_cursor_position < m_first_visibile_char) { + m_first_visibile_char = m_cursor_position; + return; + } + + if (m_cursor_position > GetLastVisibleCharPosition(width)) + m_first_visibile_char = m_cursor_position - (width - 1); + } + // The cursor is allowed to move one character past the string. // m_cursor_position is in range [0, GetContentLength()]. void MoveCursorRight() { @@ -1174,47 +1190,65 @@ public: m_cursor_position--; } - // If the cursor moved past the last visible character, scroll right by one - // character. - void ScrollRightIfNeeded() { - if (m_cursor_position - m_first_visibile_char == m_last_drawn_content_width) - m_first_visibile_char++; - } + void MoveCursorToStart() { m_cursor_position = 0; } + + void MoveCursorToEnd() { m_cursor_position = GetContentLength(); } void ScrollLeft() { if (m_first_visibile_char > 0) m_first_visibile_char--; } - // If the cursor moved past the first visible character, scroll left by one - // character. - void ScrollLeftIfNeeded() { - if (m_cursor_position < m_first_visibile_char) - m_first_visibile_char--; - } - - // Insert a character at the current cursor position, advance the cursor - // position, and make sure to scroll right if needed. + // Insert a character at the current cursor position and advance the cursor + // position. void InsertChar(char character) { m_content.insert(m_cursor_position, 1, character); m_cursor_position++; - ScrollRightIfNeeded(); + ClearError(); } // Remove the character before the cursor position, retreat the cursor - // position, and make sure to scroll left if needed. - void RemoveChar() { + // position, and scroll left. + void RemovePreviousChar() { if (m_cursor_position == 0) return; m_content.erase(m_cursor_position - 1, 1); m_cursor_position--; ScrollLeft(); + ClearError(); + } + + // Remove the character after the cursor position. + void RemoveNextChar() { + if (m_cursor_position == GetContentLength()) + return; + + m_content.erase(m_cursor_position, 1); + ClearError(); + } + + // Clear characters from the current cursor position to the end. + void ClearToEnd() { + m_content.erase(m_cursor_position); + ClearError(); + } + + void Clear() { + m_content.clear(); + m_cursor_position = 0; + ClearError(); } // True if the key represents a char that can be inserted in the field // content, false otherwise. - virtual bool IsAcceptableChar(int key) { return isprint(key); } + virtual bool IsAcceptableChar(int key) { + // The behavior of isprint is undefined when the value is not representable + // as an unsigned char. So explicitly check for non-ascii key codes. + if (key > 127) + return false; + return isprint(key); + } HandleCharResult FieldDelegateHandleChar(int key) override { if (IsAcceptableChar(key)) { @@ -1224,17 +1258,36 @@ public: } switch (key) { + case KEY_HOME: + case KEY_CTRL_A: + MoveCursorToStart(); + return eKeyHandled; + case KEY_END: + case KEY_CTRL_E: + MoveCursorToEnd(); + return eKeyHandled; case KEY_RIGHT: + case KEY_SF: MoveCursorRight(); - ScrollRightIfNeeded(); return eKeyHandled; case KEY_LEFT: + case KEY_SR: MoveCursorLeft(); - ScrollLeftIfNeeded(); return eKeyHandled; case KEY_BACKSPACE: - ClearError(); - RemoveChar(); + case KEY_DELETE: + RemovePreviousChar(); + return eKeyHandled; + case KEY_DC: + RemoveNextChar(); + return eKeyHandled; + case KEY_EOL: + case KEY_CTRL_K: + ClearToEnd(); + return eKeyHandled; + case KEY_DL: + case KEY_CLEAR: + Clear(); return eKeyHandled; default: break; @@ -1259,6 +1312,14 @@ public: const std::string &GetText() { return m_content; } + void SetText(const char *text) { + if (text == nullptr) { + m_content.clear(); + return; + } + m_content = text; + } + protected: std::string m_label; bool m_required; @@ -1269,9 +1330,6 @@ protected: int m_cursor_position; // The index of the first visible character in the content. int m_first_visibile_char; - // The width of the fields content that was last drawn. Width can change, so - // this is used to determine if scrolling is needed dynamically. - int m_last_drawn_content_width; // Optional error message. If empty, field is considered to have no error. std::string m_error; }; @@ -1405,7 +1463,7 @@ public: // Boolean fields are have a single line. int FieldDelegateGetHeight() override { return 1; } - void FieldDelegateDraw(SubPad &surface, bool is_selected) override { + void FieldDelegateDraw(Surface &surface, bool is_selected) override { surface.MoveCursor(0, 0); surface.PutChar('['); if (is_selected) @@ -1485,7 +1543,7 @@ public: return std::min(index, GetNumberOfChoices()) - 1; } - void DrawContent(SubPad &surface, bool is_selected) { + void DrawContent(Surface &surface, bool is_selected) { int choices_to_draw = GetLastVisibleChoice() - m_first_visibile_choice + 1; for (int i = 0; i < choices_to_draw; i++) { surface.MoveCursor(0, i); @@ -1501,14 +1559,14 @@ public: } } - void FieldDelegateDraw(SubPad &surface, bool is_selected) override { + void FieldDelegateDraw(Surface &surface, bool is_selected) override { UpdateScrolling(); surface.TitledBox(m_label.c_str()); Rect content_bounds = surface.GetFrame(); content_bounds.Inset(1, 1); - SubPad content_surface = SubPad(surface, content_bounds); + Surface content_surface = surface.SubSurface(content_bounds); DrawContent(content_surface, is_selected); } @@ -1584,8 +1642,10 @@ public: std::vector<std::string> GetPossiblePluginNames() { std::vector<std::string> names; size_t i = 0; - while (auto name = PluginManager::GetPlatformPluginNameAtIndex(i++)) - names.push_back(name); + for (llvm::StringRef name = + PluginManager::GetPlatformPluginNameAtIndex(i++); + !name.empty(); name = PluginManager::GetProcessPluginNameAtIndex(i++)) + names.push_back(name.str()); return names; } @@ -1605,8 +1665,9 @@ public: names.push_back("<default>"); size_t i = 0; - while (auto name = PluginManager::GetProcessPluginNameAtIndex(i++)) - names.push_back(name); + for (llvm::StringRef name = PluginManager::GetProcessPluginNameAtIndex(i++); + !name.empty(); name = PluginManager::GetProcessPluginNameAtIndex(i++)) + names.push_back(name.str()); return names; } @@ -1618,6 +1679,33 @@ public: } }; +class LazyBooleanFieldDelegate : public ChoicesFieldDelegate { +public: + LazyBooleanFieldDelegate(const char *label, const char *calculate_label) + : ChoicesFieldDelegate(label, 3, GetPossibleOptions(calculate_label)) {} + + static constexpr const char *kNo = "No"; + static constexpr const char *kYes = "Yes"; + + std::vector<std::string> GetPossibleOptions(const char *calculate_label) { + std::vector<std::string> options; + options.push_back(calculate_label); + options.push_back(kYes); + options.push_back(kNo); + return options; + } + + LazyBool GetLazyBoolean() { + std::string choice = GetChoiceContent(); + if (choice == kNo) + return eLazyBoolNo; + else if (choice == kYes) + return eLazyBoolYes; + else + return eLazyBoolCalculate; + } +}; + template <class T> class ListFieldDelegate : public FieldDelegate { public: ListFieldDelegate(const char *label, T default_field) @@ -1683,7 +1771,7 @@ public: return context; } - void DrawRemoveButton(SubPad &surface, int highlight) { + void DrawRemoveButton(Surface &surface, int highlight) { surface.MoveCursor(1, surface.GetHeight() / 2); if (highlight) surface.AttributeOn(A_REVERSE); @@ -1692,7 +1780,7 @@ public: surface.AttributeOff(A_REVERSE); } - void DrawFields(SubPad &surface, bool is_selected) { + void DrawFields(Surface &surface, bool is_selected) { int line = 0; int width = surface.GetWidth(); for (int i = 0; i < GetNumberOfFields(); i++) { @@ -1701,8 +1789,8 @@ public: Rect field_bounds, remove_button_bounds; bounds.VerticalSplit(bounds.size.width - sizeof(" [Remove]"), field_bounds, remove_button_bounds); - SubPad field_surface = SubPad(surface, field_bounds); - SubPad remove_button_surface = SubPad(surface, remove_button_bounds); + Surface field_surface = surface.SubSurface(field_bounds); + Surface remove_button_surface = surface.SubSurface(remove_button_bounds); bool is_element_selected = m_selection_index == i && is_selected; bool is_field_selected = @@ -1717,7 +1805,7 @@ public: } } - void DrawNewButton(SubPad &surface, bool is_selected) { + void DrawNewButton(Surface &surface, bool is_selected) { const char *button_text = "[New]"; int x = (surface.GetWidth() - sizeof(button_text) - 1) / 2; surface.MoveCursor(x, 0); @@ -1730,7 +1818,7 @@ public: surface.AttributeOff(A_REVERSE); } - void FieldDelegateDraw(SubPad &surface, bool is_selected) override { + void FieldDelegateDraw(Surface &surface, bool is_selected) override { surface.TitledBox(m_label.c_str()); Rect content_bounds = surface.GetFrame(); @@ -1738,8 +1826,8 @@ public: Rect fields_bounds, new_button_bounds; content_bounds.HorizontalSplit(content_bounds.size.height - 1, fields_bounds, new_button_bounds); - SubPad fields_surface = SubPad(surface, fields_bounds); - SubPad new_button_surface = SubPad(surface, new_button_bounds); + Surface fields_surface = surface.SubSurface(fields_bounds); + Surface new_button_surface = surface.SubSurface(new_button_bounds); DrawFields(fields_surface, is_selected); DrawNewButton(new_button_surface, is_selected); @@ -1822,6 +1910,31 @@ public: return eKeyHandled; } + // If the last element of the field is selected and it didn't handle the key. + // Select the next field or new button if the selected field is the last one. + HandleCharResult SelectNextInList(int key) { + assert(m_selection_type == SelectionType::Field); + + FieldDelegate &field = m_fields[m_selection_index]; + if (field.FieldDelegateHandleChar(key) == eKeyHandled) + return eKeyHandled; + + if (!field.FieldDelegateOnLastOrOnlyElement()) + return eKeyNotHandled; + + field.FieldDelegateExitCallback(); + + if (m_selection_index == GetNumberOfFields() - 1) { + m_selection_type = SelectionType::NewButton; + return eKeyHandled; + } + + m_selection_index++; + FieldDelegate &next_field = m_fields[m_selection_index]; + next_field.FieldDelegateSelectFirstElement(); + return eKeyHandled; + } + HandleCharResult FieldDelegateHandleChar(int key) override { switch (key) { case '\r': @@ -1834,16 +1947,14 @@ public: case SelectionType::RemoveButton: RemoveField(); return eKeyHandled; - default: - break; + case SelectionType::Field: + return SelectNextInList(key); } break; case '\t': - SelectNext(key); - return eKeyHandled; + return SelectNext(key); case KEY_SHIFT_TAB: - SelectPrevious(key); - return eKeyHandled; + return SelectPrevious(key); default: break; } @@ -1908,6 +2019,241 @@ protected: SelectionType m_selection_type; }; +class ArgumentsFieldDelegate : public ListFieldDelegate<TextFieldDelegate> { +public: + ArgumentsFieldDelegate() + : ListFieldDelegate("Arguments", + TextFieldDelegate("Argument", "", false)) {} + + Args GetArguments() { + Args arguments; + for (int i = 0; i < GetNumberOfFields(); i++) { + arguments.AppendArgument(GetField(i).GetText()); + } + return arguments; + } + + void AddArguments(const Args &arguments) { + for (size_t i = 0; i < arguments.GetArgumentCount(); i++) { + AddNewField(); + TextFieldDelegate &field = GetField(GetNumberOfFields() - 1); + field.SetText(arguments.GetArgumentAtIndex(i)); + } + } +}; + +template <class KeyFieldDelegateType, class ValueFieldDelegateType> +class MappingFieldDelegate : public FieldDelegate { +public: + MappingFieldDelegate(KeyFieldDelegateType key_field, + ValueFieldDelegateType value_field) + : m_key_field(key_field), m_value_field(value_field), + m_selection_type(SelectionType::Key) {} + + // Signify which element is selected. The key field or its value field. + enum class SelectionType { Key, Value }; + + // A mapping field is drawn as two text fields with a right arrow in between. + // The first field stores the key of the mapping and the second stores the + // value if the mapping. + // + // __[Key]_____________ __[Value]___________ + // | | > | | + // |__________________| |__________________| + // - Error message if it exists. + + // The mapping field has a height that is equal to the maximum height between + // the key and value fields. + int FieldDelegateGetHeight() override { + return std::max(m_key_field.FieldDelegateGetHeight(), + m_value_field.FieldDelegateGetHeight()); + } + + void DrawArrow(Surface &surface) { + surface.MoveCursor(0, 1); + surface.PutChar(ACS_RARROW); + } + + void FieldDelegateDraw(Surface &surface, bool is_selected) override { + Rect bounds = surface.GetFrame(); + Rect key_field_bounds, arrow_and_value_field_bounds; + bounds.VerticalSplit(bounds.size.width / 2, key_field_bounds, + arrow_and_value_field_bounds); + Rect arrow_bounds, value_field_bounds; + arrow_and_value_field_bounds.VerticalSplit(1, arrow_bounds, + value_field_bounds); + + Surface key_field_surface = surface.SubSurface(key_field_bounds); + Surface arrow_surface = surface.SubSurface(arrow_bounds); + Surface value_field_surface = surface.SubSurface(value_field_bounds); + + bool key_is_selected = + m_selection_type == SelectionType::Key && is_selected; + m_key_field.FieldDelegateDraw(key_field_surface, key_is_selected); + DrawArrow(arrow_surface); + bool value_is_selected = + m_selection_type == SelectionType::Value && is_selected; + m_value_field.FieldDelegateDraw(value_field_surface, value_is_selected); + } + + HandleCharResult SelectNext(int key) { + if (FieldDelegateOnLastOrOnlyElement()) + return eKeyNotHandled; + + if (!m_key_field.FieldDelegateOnLastOrOnlyElement()) { + return m_key_field.FieldDelegateHandleChar(key); + } + + m_key_field.FieldDelegateExitCallback(); + m_selection_type = SelectionType::Value; + m_value_field.FieldDelegateSelectFirstElement(); + return eKeyHandled; + } + + HandleCharResult SelectPrevious(int key) { + if (FieldDelegateOnFirstOrOnlyElement()) + return eKeyNotHandled; + + if (!m_value_field.FieldDelegateOnFirstOrOnlyElement()) { + return m_value_field.FieldDelegateHandleChar(key); + } + + m_value_field.FieldDelegateExitCallback(); + m_selection_type = SelectionType::Key; + m_key_field.FieldDelegateSelectLastElement(); + return eKeyHandled; + } + + // If the value field is selected, pass the key to it. If the key field is + // selected, its last element is selected, and it didn't handle the key, then + // select its corresponding value field. + HandleCharResult SelectNextField(int key) { + if (m_selection_type == SelectionType::Value) { + return m_value_field.FieldDelegateHandleChar(key); + } + + if (m_key_field.FieldDelegateHandleChar(key) == eKeyHandled) + return eKeyHandled; + + if (!m_key_field.FieldDelegateOnLastOrOnlyElement()) + return eKeyNotHandled; + + m_key_field.FieldDelegateExitCallback(); + m_selection_type = SelectionType::Value; + m_value_field.FieldDelegateSelectFirstElement(); + return eKeyHandled; + } + + HandleCharResult FieldDelegateHandleChar(int key) override { + switch (key) { + case KEY_RETURN: + return SelectNextField(key); + case '\t': + return SelectNext(key); + case KEY_SHIFT_TAB: + return SelectPrevious(key); + default: + break; + } + + // If the key wasn't handled, pass the key to the selected field. + if (m_selection_type == SelectionType::Key) + return m_key_field.FieldDelegateHandleChar(key); + else + return m_value_field.FieldDelegateHandleChar(key); + + return eKeyNotHandled; + } + + bool FieldDelegateOnFirstOrOnlyElement() override { + return m_selection_type == SelectionType::Key; + } + + bool FieldDelegateOnLastOrOnlyElement() override { + return m_selection_type == SelectionType::Value; + } + + void FieldDelegateSelectFirstElement() override { + m_selection_type = SelectionType::Key; + } + + void FieldDelegateSelectLastElement() override { + m_selection_type = SelectionType::Value; + } + + bool FieldDelegateHasError() override { + return m_key_field.FieldDelegateHasError() || + m_value_field.FieldDelegateHasError(); + } + + KeyFieldDelegateType &GetKeyField() { return m_key_field; } + + ValueFieldDelegateType &GetValueField() { return m_value_field; } + +protected: + KeyFieldDelegateType m_key_field; + ValueFieldDelegateType m_value_field; + // See SelectionType class enum. + SelectionType m_selection_type; +}; + +class EnvironmentVariableNameFieldDelegate : public TextFieldDelegate { +public: + EnvironmentVariableNameFieldDelegate(const char *content) + : TextFieldDelegate("Name", content, true) {} + + // Environment variable names can't contain an equal sign. + bool IsAcceptableChar(int key) override { + return TextFieldDelegate::IsAcceptableChar(key) && key != '='; + } + + const std::string &GetName() { return m_content; } +}; + +class EnvironmentVariableFieldDelegate + : public MappingFieldDelegate<EnvironmentVariableNameFieldDelegate, + TextFieldDelegate> { +public: + EnvironmentVariableFieldDelegate() + : MappingFieldDelegate( + EnvironmentVariableNameFieldDelegate(""), + TextFieldDelegate("Value", "", /*required=*/false)) {} + + const std::string &GetName() { return GetKeyField().GetName(); } + + const std::string &GetValue() { return GetValueField().GetText(); } + + void SetName(const char *name) { return GetKeyField().SetText(name); } + + void SetValue(const char *value) { return GetValueField().SetText(value); } +}; + +class EnvironmentVariableListFieldDelegate + : public ListFieldDelegate<EnvironmentVariableFieldDelegate> { +public: + EnvironmentVariableListFieldDelegate(const char *label) + : ListFieldDelegate(label, EnvironmentVariableFieldDelegate()) {} + + Environment GetEnvironment() { + Environment environment; + for (int i = 0; i < GetNumberOfFields(); i++) { + environment.insert( + std::make_pair(GetField(i).GetName(), GetField(i).GetValue())); + } + return environment; + } + + void AddEnvironmentVariables(const Environment &environment) { + for (auto &variable : environment) { + AddNewField(); + EnvironmentVariableFieldDelegate &field = + GetField(GetNumberOfFields() - 1); + field.SetName(variable.getKey().str().c_str()); + field.SetValue(variable.getValue().c_str()); + } + } +}; + class FormAction { public: FormAction(const char *label, std::function<void(Window &)> action) @@ -1917,7 +2263,7 @@ public: } // Draw a centered [Label]. - void Draw(SubPad &surface, bool is_selected) { + void Draw(Surface &surface, bool is_selected) { int x = (surface.GetWidth() - m_label.length()) / 2; surface.MoveCursor(x, 0); if (is_selected) @@ -1973,6 +2319,7 @@ public: // action that requires valid fields. bool CheckFieldsValidity() { for (int i = 0; i < GetNumberOfFields(); i++) { + GetField(i)->FieldDelegateExitCallback(); if (GetField(i)->FieldDelegateHasError()) { SetError("Some fields are invalid!"); return false; @@ -2030,6 +2377,14 @@ public: return delegate; } + LazyBooleanFieldDelegate *AddLazyBooleanField(const char *label, + const char *calculate_label) { + LazyBooleanFieldDelegate *delegate = + new LazyBooleanFieldDelegate(label, calculate_label); + m_fields.push_back(FieldDelegateUP(delegate)); + return delegate; + } + ChoicesFieldDelegate *AddChoicesField(const char *label, int height, std::vector<std::string> choices) { ChoicesFieldDelegate *delegate = @@ -2059,6 +2414,43 @@ public: return delegate; } + ArgumentsFieldDelegate *AddArgumentsField() { + ArgumentsFieldDelegate *delegate = new ArgumentsFieldDelegate(); + m_fields.push_back(FieldDelegateUP(delegate)); + return delegate; + } + + template <class K, class V> + MappingFieldDelegate<K, V> *AddMappingField(K key_field, V value_field) { + MappingFieldDelegate<K, V> *delegate = + new MappingFieldDelegate<K, V>(key_field, value_field); + m_fields.push_back(FieldDelegateUP(delegate)); + return delegate; + } + + EnvironmentVariableNameFieldDelegate * + AddEnvironmentVariableNameField(const char *content) { + EnvironmentVariableNameFieldDelegate *delegate = + new EnvironmentVariableNameFieldDelegate(content); + m_fields.push_back(FieldDelegateUP(delegate)); + return delegate; + } + + EnvironmentVariableFieldDelegate *AddEnvironmentVariableField() { + EnvironmentVariableFieldDelegate *delegate = + new EnvironmentVariableFieldDelegate(); + m_fields.push_back(FieldDelegateUP(delegate)); + return delegate; + } + + EnvironmentVariableListFieldDelegate * + AddEnvironmentVariableListField(const char *label) { + EnvironmentVariableListFieldDelegate *delegate = + new EnvironmentVariableListFieldDelegate(label); + m_fields.push_back(FieldDelegateUP(delegate)); + return delegate; + } + // Factory methods for adding actions. void AddAction(const char *label, std::function<void(Window &)> action) { @@ -2156,7 +2548,7 @@ public: return context; } - void UpdateScrolling(DerivedWindow &surface) { + void UpdateScrolling(Surface &surface) { ScrollContext context = GetScrollContext(); int content_height = GetContentHeight(); int surface_height = surface.GetHeight(); @@ -2180,7 +2572,7 @@ public: } } - void DrawError(SubPad &surface) { + void DrawError(Surface &surface) { if (!m_delegate_sp->HasError()) return; surface.MoveCursor(0, 0); @@ -2194,7 +2586,7 @@ public: surface.HorizontalLine(surface.GetWidth()); } - void DrawFields(SubPad &surface) { + void DrawFields(Surface &surface) { int line = 0; int width = surface.GetWidth(); bool a_field_is_selected = m_selection_type == SelectionType::Field; @@ -2205,13 +2597,13 @@ public: bool is_field_selected = a_field_is_selected && m_selection_index == i; int height = field->FieldDelegateGetHeight(); Rect bounds = Rect(Point(0, line), Size(width, height)); - SubPad field_surface = SubPad(surface, bounds); + Surface field_surface = surface.SubSurface(bounds); field->FieldDelegateDraw(field_surface, is_field_selected); line += height; } } - void DrawActions(SubPad &surface) { + void DrawActions(Surface &surface) { int number_of_actions = m_delegate_sp->GetNumberOfActions(); int width = surface.GetWidth() / number_of_actions; bool an_action_is_selected = m_selection_type == SelectionType::Action; @@ -2220,19 +2612,19 @@ public: bool is_action_selected = an_action_is_selected && m_selection_index == i; FormAction &action = m_delegate_sp->GetAction(i); Rect bounds = Rect(Point(x, 0), Size(width, 1)); - SubPad action_surface = SubPad(surface, bounds); + Surface action_surface = surface.SubSurface(bounds); action.Draw(action_surface, is_action_selected); x += width; } } - void DrawElements(SubPad &surface) { + void DrawElements(Surface &surface) { Rect frame = surface.GetFrame(); Rect fields_bounds, actions_bounds; frame.HorizontalSplit(surface.GetHeight() - GetActionsHeight(), fields_bounds, actions_bounds); - SubPad fields_surface = SubPad(surface, fields_bounds); - SubPad actions_surface = SubPad(surface, actions_bounds); + Surface fields_surface = surface.SubSurface(fields_bounds); + Surface actions_surface = surface.SubSurface(actions_bounds); DrawFields(fields_surface); DrawActions(actions_surface); @@ -2241,7 +2633,7 @@ public: // Contents are first drawn on a pad. Then a subset of that pad is copied to // the derived window starting at the first visible line. This essentially // provides scrolling functionality. - void DrawContent(DerivedWindow &surface) { + void DrawContent(Surface &surface) { UpdateScrolling(surface); int width = surface.GetWidth(); @@ -2251,8 +2643,8 @@ public: Rect frame = pad.GetFrame(); Rect error_bounds, elements_bounds; frame.HorizontalSplit(GetErrorHeight(), error_bounds, elements_bounds); - SubPad error_surface = SubPad(pad, error_bounds); - SubPad elements_surface = SubPad(pad, elements_bounds); + Surface error_surface = pad.SubSurface(error_bounds); + Surface elements_surface = pad.SubSurface(elements_bounds); DrawError(error_surface); DrawElements(elements_surface); @@ -2262,17 +2654,28 @@ public: Size(width, copy_height)); } + void DrawSubmitHint(Surface &surface, bool is_active) { + surface.MoveCursor(2, surface.GetHeight() - 1); + if (is_active) + surface.AttributeOn(A_BOLD | COLOR_PAIR(BlackOnWhite)); + surface.Printf("[Press Alt+Enter to %s]", + m_delegate_sp->GetAction(0).GetLabel().c_str()); + if (is_active) + surface.AttributeOff(A_BOLD | COLOR_PAIR(BlackOnWhite)); + } + bool WindowDelegateDraw(Window &window, bool force) override { m_delegate_sp->UpdateFieldsVisibility(); window.Erase(); window.DrawTitleBox(m_delegate_sp->GetName().c_str(), - "Press Esc to cancel"); + "Press Esc to Cancel"); + DrawSubmitHint(window, window.IsActive()); Rect content_bounds = window.GetFrame(); content_bounds.Inset(2, 2); - DerivedWindow content_surface = DerivedWindow(window, content_bounds); + Surface content_surface = window.SubSurface(content_bounds); DrawContent(content_surface); return true; @@ -2391,8 +2794,8 @@ public: return eKeyHandled; } - void ExecuteAction(Window &window) { - FormAction &action = m_delegate_sp->GetAction(m_selection_index); + void ExecuteAction(Window &window, int index) { + FormAction &action = m_delegate_sp->GetAction(index); action.Execute(window); if (m_delegate_sp->HasError()) { m_first_visible_line = 0; @@ -2401,20 +2804,27 @@ public: } } + // Always return eKeyHandled to absorb all events since forms are always + // added as pop-ups that should take full control until canceled or submitted. HandleCharResult WindowDelegateHandleChar(Window &window, int key) override { switch (key) { case '\r': case '\n': case KEY_ENTER: if (m_selection_type == SelectionType::Action) { - ExecuteAction(window); + ExecuteAction(window, m_selection_index); return eKeyHandled; } break; + case KEY_ALT_ENTER: + ExecuteAction(window, 0); + return eKeyHandled; case '\t': - return SelectNext(key); + SelectNext(key); + return eKeyHandled; case KEY_SHIFT_TAB: - return SelectPrevious(key); + SelectPrevious(key); + return eKeyHandled; case KEY_ESCAPE: window.GetParent()->RemoveSubWindow(&window); return eKeyHandled; @@ -2426,10 +2836,24 @@ public: // to that field. if (m_selection_type == SelectionType::Field) { FieldDelegate *field = m_delegate_sp->GetField(m_selection_index); - return field->FieldDelegateHandleChar(key); + if (field->FieldDelegateHandleChar(key) == eKeyHandled) + return eKeyHandled; } - return eKeyNotHandled; + // If the key wasn't handled by the possibly selected field, handle some + // extra keys for navigation. + switch (key) { + case KEY_DOWN: + SelectNext(key); + return eKeyHandled; + case KEY_UP: + SelectPrevious(key); + return eKeyHandled; + default: + break; + } + + return eKeyHandled; } protected: @@ -2651,6 +3075,801 @@ protected: ProcessPluginFieldDelegate *m_plugin_field; }; +class TargetCreateFormDelegate : public FormDelegate { +public: + TargetCreateFormDelegate(Debugger &debugger) : m_debugger(debugger) { + m_executable_field = AddFileField("Executable", "", /*need_to_exist=*/true, + /*required=*/true); + m_core_file_field = AddFileField("Core File", "", /*need_to_exist=*/true, + /*required=*/false); + m_symbol_file_field = AddFileField( + "Symbol File", "", /*need_to_exist=*/true, /*required=*/false); + m_show_advanced_field = AddBooleanField("Show advanced settings.", false); + m_remote_file_field = AddFileField( + "Remote File", "", /*need_to_exist=*/false, /*required=*/false); + m_arch_field = AddArchField("Architecture", "", /*required=*/false); + m_platform_field = AddPlatformPluginField(debugger); + m_load_dependent_files_field = + AddChoicesField("Load Dependents", 3, GetLoadDependentFilesChoices()); + + AddAction("Create", [this](Window &window) { CreateTarget(window); }); + } + + std::string GetName() override { return "Create Target"; } + + void UpdateFieldsVisibility() override { + if (m_show_advanced_field->GetBoolean()) { + m_remote_file_field->FieldDelegateShow(); + m_arch_field->FieldDelegateShow(); + m_platform_field->FieldDelegateShow(); + m_load_dependent_files_field->FieldDelegateShow(); + } else { + m_remote_file_field->FieldDelegateHide(); + m_arch_field->FieldDelegateHide(); + m_platform_field->FieldDelegateHide(); + m_load_dependent_files_field->FieldDelegateHide(); + } + } + + static constexpr const char *kLoadDependentFilesNo = "No"; + static constexpr const char *kLoadDependentFilesYes = "Yes"; + static constexpr const char *kLoadDependentFilesExecOnly = "Executable only"; + + std::vector<std::string> GetLoadDependentFilesChoices() { + std::vector<std::string> load_depentents_options; + load_depentents_options.push_back(kLoadDependentFilesExecOnly); + load_depentents_options.push_back(kLoadDependentFilesYes); + load_depentents_options.push_back(kLoadDependentFilesNo); + return load_depentents_options; + } + + LoadDependentFiles GetLoadDependentFiles() { + std::string choice = m_load_dependent_files_field->GetChoiceContent(); + if (choice == kLoadDependentFilesNo) + return eLoadDependentsNo; + if (choice == kLoadDependentFilesYes) + return eLoadDependentsYes; + return eLoadDependentsDefault; + } + + OptionGroupPlatform GetPlatformOptions() { + OptionGroupPlatform platform_options(false); + platform_options.SetPlatformName(m_platform_field->GetPluginName().c_str()); + return platform_options; + } + + TargetSP GetTarget() { + OptionGroupPlatform platform_options = GetPlatformOptions(); + TargetSP target_sp; + Status status = m_debugger.GetTargetList().CreateTarget( + m_debugger, m_executable_field->GetPath(), + m_arch_field->GetArchString(), GetLoadDependentFiles(), + &platform_options, target_sp); + + if (status.Fail()) { + SetError(status.AsCString()); + return nullptr; + } + + m_debugger.GetTargetList().SetSelectedTarget(target_sp); + + return target_sp; + } + + void SetSymbolFile(TargetSP target_sp) { + if (!m_symbol_file_field->IsSpecified()) + return; + + ModuleSP module_sp(target_sp->GetExecutableModule()); + if (!module_sp) + return; + + module_sp->SetSymbolFileFileSpec( + m_symbol_file_field->GetResolvedFileSpec()); + } + + void SetCoreFile(TargetSP target_sp) { + if (!m_core_file_field->IsSpecified()) + return; + + FileSpec core_file_spec = m_core_file_field->GetResolvedFileSpec(); + + FileSpec core_file_directory_spec; + core_file_directory_spec.GetDirectory() = core_file_spec.GetDirectory(); + target_sp->AppendExecutableSearchPaths(core_file_directory_spec); + + ProcessSP process_sp(target_sp->CreateProcess( + m_debugger.GetListener(), llvm::StringRef(), &core_file_spec, false)); + + if (!process_sp) { + SetError("Unable to find process plug-in for core file!"); + return; + } + + Status status = process_sp->LoadCore(); + if (status.Fail()) { + SetError("Can't find plug-in for core file!"); + return; + } + } + + void SetRemoteFile(TargetSP target_sp) { + if (!m_remote_file_field->IsSpecified()) + return; + + ModuleSP module_sp(target_sp->GetExecutableModule()); + if (!module_sp) + return; + + FileSpec remote_file_spec = m_remote_file_field->GetFileSpec(); + module_sp->SetPlatformFileSpec(remote_file_spec); + } + + void RemoveTarget(TargetSP target_sp) { + m_debugger.GetTargetList().DeleteTarget(target_sp); + } + + void CreateTarget(Window &window) { + ClearError(); + + bool all_fields_are_valid = CheckFieldsValidity(); + if (!all_fields_are_valid) + return; + + TargetSP target_sp = GetTarget(); + if (HasError()) + return; + + SetSymbolFile(target_sp); + if (HasError()) { + RemoveTarget(target_sp); + return; + } + + SetCoreFile(target_sp); + if (HasError()) { + RemoveTarget(target_sp); + return; + } + + SetRemoteFile(target_sp); + if (HasError()) { + RemoveTarget(target_sp); + return; + } + + window.GetParent()->RemoveSubWindow(&window); + } + +protected: + Debugger &m_debugger; + + FileFieldDelegate *m_executable_field; + FileFieldDelegate *m_core_file_field; + FileFieldDelegate *m_symbol_file_field; + BooleanFieldDelegate *m_show_advanced_field; + FileFieldDelegate *m_remote_file_field; + ArchFieldDelegate *m_arch_field; + PlatformPluginFieldDelegate *m_platform_field; + ChoicesFieldDelegate *m_load_dependent_files_field; +}; + +class ProcessLaunchFormDelegate : public FormDelegate { +public: + ProcessLaunchFormDelegate(Debugger &debugger, WindowSP main_window_sp) + : m_debugger(debugger), m_main_window_sp(main_window_sp) { + + m_arguments_field = AddArgumentsField(); + SetArgumentsFieldDefaultValue(); + m_target_environment_field = + AddEnvironmentVariableListField("Target Environment Variables"); + SetTargetEnvironmentFieldDefaultValue(); + m_working_directory_field = AddDirectoryField( + "Working Directory", GetDefaultWorkingDirectory().c_str(), true, false); + + m_show_advanced_field = AddBooleanField("Show advanced settings.", false); + + m_stop_at_entry_field = AddBooleanField("Stop at entry point.", false); + m_detach_on_error_field = + AddBooleanField("Detach on error.", GetDefaultDetachOnError()); + m_disable_aslr_field = + AddBooleanField("Disable ASLR", GetDefaultDisableASLR()); + m_plugin_field = AddProcessPluginField(); + m_arch_field = AddArchField("Architecture", "", false); + m_shell_field = AddFileField("Shell", "", true, false); + m_expand_shell_arguments_field = + AddBooleanField("Expand shell arguments.", false); + + m_disable_standard_io_field = + AddBooleanField("Disable Standard IO", GetDefaultDisableStandardIO()); + m_standard_output_field = + AddFileField("Standard Output File", "", /*need_to_exist=*/false, + /*required=*/false); + m_standard_error_field = + AddFileField("Standard Error File", "", /*need_to_exist=*/false, + /*required=*/false); + m_standard_input_field = + AddFileField("Standard Input File", "", /*need_to_exist=*/false, + /*required=*/false); + + m_show_inherited_environment_field = + AddBooleanField("Show inherited environment variables.", false); + m_inherited_environment_field = + AddEnvironmentVariableListField("Inherited Environment Variables"); + SetInheritedEnvironmentFieldDefaultValue(); + + AddAction("Launch", [this](Window &window) { Launch(window); }); + } + + std::string GetName() override { return "Launch Process"; } + + void UpdateFieldsVisibility() override { + if (m_show_advanced_field->GetBoolean()) { + m_stop_at_entry_field->FieldDelegateShow(); + m_detach_on_error_field->FieldDelegateShow(); + m_disable_aslr_field->FieldDelegateShow(); + m_plugin_field->FieldDelegateShow(); + m_arch_field->FieldDelegateShow(); + m_shell_field->FieldDelegateShow(); + m_expand_shell_arguments_field->FieldDelegateShow(); + m_disable_standard_io_field->FieldDelegateShow(); + if (m_disable_standard_io_field->GetBoolean()) { + m_standard_input_field->FieldDelegateHide(); + m_standard_output_field->FieldDelegateHide(); + m_standard_error_field->FieldDelegateHide(); + } else { + m_standard_input_field->FieldDelegateShow(); + m_standard_output_field->FieldDelegateShow(); + m_standard_error_field->FieldDelegateShow(); + } + m_show_inherited_environment_field->FieldDelegateShow(); + if (m_show_inherited_environment_field->GetBoolean()) + m_inherited_environment_field->FieldDelegateShow(); + else + m_inherited_environment_field->FieldDelegateHide(); + } else { + m_stop_at_entry_field->FieldDelegateHide(); + m_detach_on_error_field->FieldDelegateHide(); + m_disable_aslr_field->FieldDelegateHide(); + m_plugin_field->FieldDelegateHide(); + m_arch_field->FieldDelegateHide(); + m_shell_field->FieldDelegateHide(); + m_expand_shell_arguments_field->FieldDelegateHide(); + m_disable_standard_io_field->FieldDelegateHide(); + m_standard_input_field->FieldDelegateHide(); + m_standard_output_field->FieldDelegateHide(); + m_standard_error_field->FieldDelegateHide(); + m_show_inherited_environment_field->FieldDelegateHide(); + m_inherited_environment_field->FieldDelegateHide(); + } + } + + // Methods for setting the default value of the fields. + + void SetArgumentsFieldDefaultValue() { + TargetSP target = m_debugger.GetSelectedTarget(); + if (target == nullptr) + return; + + const Args &target_arguments = + target->GetProcessLaunchInfo().GetArguments(); + m_arguments_field->AddArguments(target_arguments); + } + + void SetTargetEnvironmentFieldDefaultValue() { + TargetSP target = m_debugger.GetSelectedTarget(); + if (target == nullptr) + return; + + const Environment &target_environment = target->GetTargetEnvironment(); + m_target_environment_field->AddEnvironmentVariables(target_environment); + } + + void SetInheritedEnvironmentFieldDefaultValue() { + TargetSP target = m_debugger.GetSelectedTarget(); + if (target == nullptr) + return; + + const Environment &inherited_environment = + target->GetInheritedEnvironment(); + m_inherited_environment_field->AddEnvironmentVariables( + inherited_environment); + } + + std::string GetDefaultWorkingDirectory() { + TargetSP target = m_debugger.GetSelectedTarget(); + if (target == nullptr) + return ""; + + PlatformSP platform = target->GetPlatform(); + return platform->GetWorkingDirectory().GetPath(); + } + + bool GetDefaultDisableASLR() { + TargetSP target = m_debugger.GetSelectedTarget(); + if (target == nullptr) + return false; + + return target->GetDisableASLR(); + } + + bool GetDefaultDisableStandardIO() { + TargetSP target = m_debugger.GetSelectedTarget(); + if (target == nullptr) + return true; + + return target->GetDisableSTDIO(); + } + + bool GetDefaultDetachOnError() { + TargetSP target = m_debugger.GetSelectedTarget(); + if (target == nullptr) + return true; + + return target->GetDetachOnError(); + } + + // Methods for getting the necessary information and setting them to the + // ProcessLaunchInfo. + + void GetExecutableSettings(ProcessLaunchInfo &launch_info) { + TargetSP target = m_debugger.GetSelectedTarget(); + ModuleSP executable_module = target->GetExecutableModule(); + llvm::StringRef target_settings_argv0 = target->GetArg0(); + + if (!target_settings_argv0.empty()) { + launch_info.GetArguments().AppendArgument(target_settings_argv0); + launch_info.SetExecutableFile(executable_module->GetPlatformFileSpec(), + false); + return; + } + + launch_info.SetExecutableFile(executable_module->GetPlatformFileSpec(), + true); + } + + void GetArguments(ProcessLaunchInfo &launch_info) { + TargetSP target = m_debugger.GetSelectedTarget(); + Args arguments = m_arguments_field->GetArguments(); + launch_info.GetArguments().AppendArguments(arguments); + } + + void GetEnvironment(ProcessLaunchInfo &launch_info) { + Environment target_environment = + m_target_environment_field->GetEnvironment(); + Environment inherited_environment = + m_inherited_environment_field->GetEnvironment(); + launch_info.GetEnvironment().insert(target_environment.begin(), + target_environment.end()); + launch_info.GetEnvironment().insert(inherited_environment.begin(), + inherited_environment.end()); + } + + void GetWorkingDirectory(ProcessLaunchInfo &launch_info) { + if (m_working_directory_field->IsSpecified()) + launch_info.SetWorkingDirectory( + m_working_directory_field->GetResolvedFileSpec()); + } + + void GetStopAtEntry(ProcessLaunchInfo &launch_info) { + if (m_stop_at_entry_field->GetBoolean()) + launch_info.GetFlags().Set(eLaunchFlagStopAtEntry); + else + launch_info.GetFlags().Clear(eLaunchFlagStopAtEntry); + } + + void GetDetachOnError(ProcessLaunchInfo &launch_info) { + if (m_detach_on_error_field->GetBoolean()) + launch_info.GetFlags().Set(eLaunchFlagDetachOnError); + else + launch_info.GetFlags().Clear(eLaunchFlagDetachOnError); + } + + void GetDisableASLR(ProcessLaunchInfo &launch_info) { + if (m_disable_aslr_field->GetBoolean()) + launch_info.GetFlags().Set(eLaunchFlagDisableASLR); + else + launch_info.GetFlags().Clear(eLaunchFlagDisableASLR); + } + + void GetPlugin(ProcessLaunchInfo &launch_info) { + launch_info.SetProcessPluginName(m_plugin_field->GetPluginName()); + } + + void GetArch(ProcessLaunchInfo &launch_info) { + if (!m_arch_field->IsSpecified()) + return; + + TargetSP target_sp = m_debugger.GetSelectedTarget(); + PlatformSP platform_sp = + target_sp ? target_sp->GetPlatform() : PlatformSP(); + launch_info.GetArchitecture() = Platform::GetAugmentedArchSpec( + platform_sp.get(), m_arch_field->GetArchString()); + } + + void GetShell(ProcessLaunchInfo &launch_info) { + if (!m_shell_field->IsSpecified()) + return; + + launch_info.SetShell(m_shell_field->GetResolvedFileSpec()); + launch_info.SetShellExpandArguments( + m_expand_shell_arguments_field->GetBoolean()); + } + + void GetStandardIO(ProcessLaunchInfo &launch_info) { + if (m_disable_standard_io_field->GetBoolean()) { + launch_info.GetFlags().Set(eLaunchFlagDisableSTDIO); + return; + } + + FileAction action; + if (m_standard_input_field->IsSpecified()) { + action.Open(STDIN_FILENO, m_standard_input_field->GetFileSpec(), true, + false); + launch_info.AppendFileAction(action); + } + if (m_standard_output_field->IsSpecified()) { + action.Open(STDOUT_FILENO, m_standard_output_field->GetFileSpec(), false, + true); + launch_info.AppendFileAction(action); + } + if (m_standard_error_field->IsSpecified()) { + action.Open(STDERR_FILENO, m_standard_error_field->GetFileSpec(), false, + true); + launch_info.AppendFileAction(action); + } + } + + void GetInheritTCC(ProcessLaunchInfo &launch_info) { + if (m_debugger.GetSelectedTarget()->GetInheritTCC()) + launch_info.GetFlags().Set(eLaunchFlagInheritTCCFromParent); + } + + ProcessLaunchInfo GetLaunchInfo() { + ProcessLaunchInfo launch_info; + + GetExecutableSettings(launch_info); + GetArguments(launch_info); + GetEnvironment(launch_info); + GetWorkingDirectory(launch_info); + GetStopAtEntry(launch_info); + GetDetachOnError(launch_info); + GetDisableASLR(launch_info); + GetPlugin(launch_info); + GetArch(launch_info); + GetShell(launch_info); + GetStandardIO(launch_info); + GetInheritTCC(launch_info); + + return launch_info; + } + + bool StopRunningProcess() { + ExecutionContext exe_ctx = + m_debugger.GetCommandInterpreter().GetExecutionContext(); + + if (!exe_ctx.HasProcessScope()) + return false; + + Process *process = exe_ctx.GetProcessPtr(); + if (!(process && process->IsAlive())) + return false; + + FormDelegateSP form_delegate_sp = + FormDelegateSP(new DetachOrKillProcessFormDelegate(process)); + Rect bounds = m_main_window_sp->GetCenteredRect(85, 8); + WindowSP form_window_sp = m_main_window_sp->CreateSubWindow( + form_delegate_sp->GetName().c_str(), bounds, true); + WindowDelegateSP window_delegate_sp = + WindowDelegateSP(new FormWindowDelegate(form_delegate_sp)); + form_window_sp->SetDelegate(window_delegate_sp); + + return true; + } + + Target *GetTarget() { + Target *target = m_debugger.GetSelectedTarget().get(); + + if (target == nullptr) { + SetError("No target exists!"); + return nullptr; + } + + ModuleSP exe_module_sp = target->GetExecutableModule(); + + if (exe_module_sp == nullptr) { + SetError("No executable in target!"); + return nullptr; + } + + return target; + } + + void Launch(Window &window) { + ClearError(); + + bool all_fields_are_valid = CheckFieldsValidity(); + if (!all_fields_are_valid) + return; + + bool process_is_running = StopRunningProcess(); + if (process_is_running) + return; + + Target *target = GetTarget(); + if (HasError()) + return; + + StreamString stream; + ProcessLaunchInfo launch_info = GetLaunchInfo(); + Status status = target->Launch(launch_info, &stream); + + if (status.Fail()) { + SetError(status.AsCString()); + return; + } + + ProcessSP process_sp(target->GetProcessSP()); + if (!process_sp) { + SetError("Launched successfully but target has no process!"); + return; + } + + window.GetParent()->RemoveSubWindow(&window); + } + +protected: + Debugger &m_debugger; + WindowSP m_main_window_sp; + + ArgumentsFieldDelegate *m_arguments_field; + EnvironmentVariableListFieldDelegate *m_target_environment_field; + DirectoryFieldDelegate *m_working_directory_field; + + BooleanFieldDelegate *m_show_advanced_field; + + BooleanFieldDelegate *m_stop_at_entry_field; + BooleanFieldDelegate *m_detach_on_error_field; + BooleanFieldDelegate *m_disable_aslr_field; + ProcessPluginFieldDelegate *m_plugin_field; + ArchFieldDelegate *m_arch_field; + FileFieldDelegate *m_shell_field; + BooleanFieldDelegate *m_expand_shell_arguments_field; + BooleanFieldDelegate *m_disable_standard_io_field; + FileFieldDelegate *m_standard_input_field; + FileFieldDelegate *m_standard_output_field; + FileFieldDelegate *m_standard_error_field; + + BooleanFieldDelegate *m_show_inherited_environment_field; + EnvironmentVariableListFieldDelegate *m_inherited_environment_field; +}; + +//////////// +// Searchers +//////////// + +class SearcherDelegate { +public: + SearcherDelegate() {} + + virtual ~SearcherDelegate() = default; + + virtual int GetNumberOfMatches() = 0; + + // Get the string that will be displayed for the match at the input index. + virtual const std::string &GetMatchTextAtIndex(int index) = 0; + + // Update the matches of the search. This is executed every time the text + // field handles an event. + virtual void UpdateMatches(const std::string &text) = 0; + + // Execute the user callback given the index of some match. This is executed + // once the user selects a match. + virtual void ExecuteCallback(int match_index) = 0; +}; + +typedef std::shared_ptr<SearcherDelegate> SearcherDelegateSP; + +class SearcherWindowDelegate : public WindowDelegate { +public: + SearcherWindowDelegate(SearcherDelegateSP &delegate_sp) + : m_delegate_sp(delegate_sp), m_text_field("Search", "", false), + m_selected_match(0), m_first_visible_match(0) { + ; + } + + // A completion window is padded by one character from all sides. A text field + // is first drawn for inputting the searcher request, then a list of matches + // are displayed in a scrollable list. + // + // ___<Searcher Window Name>____________________________ + // | | + // | __[Search]_______________________________________ | + // | | | | + // | |_______________________________________________| | + // | - Match 1. | + // | - Match 2. | + // | - ... | + // | | + // |____________________________[Press Esc to Cancel]__| + // + + // Get the index of the last visible match. Assuming at least one match + // exists. + int GetLastVisibleMatch(int height) { + int index = m_first_visible_match + height; + return std::min(index, m_delegate_sp->GetNumberOfMatches()) - 1; + } + + int GetNumberOfVisibleMatches(int height) { + return GetLastVisibleMatch(height) - m_first_visible_match + 1; + } + + void UpdateScrolling(Surface &surface) { + if (m_selected_match < m_first_visible_match) { + m_first_visible_match = m_selected_match; + return; + } + + int height = surface.GetHeight(); + int last_visible_match = GetLastVisibleMatch(height); + if (m_selected_match > last_visible_match) { + m_first_visible_match = m_selected_match - height + 1; + } + } + + void DrawMatches(Surface &surface) { + if (m_delegate_sp->GetNumberOfMatches() == 0) + return; + + UpdateScrolling(surface); + + int count = GetNumberOfVisibleMatches(surface.GetHeight()); + for (int i = 0; i < count; i++) { + surface.MoveCursor(1, i); + int current_match = m_first_visible_match + i; + if (current_match == m_selected_match) + surface.AttributeOn(A_REVERSE); + surface.PutCString( + m_delegate_sp->GetMatchTextAtIndex(current_match).c_str()); + if (current_match == m_selected_match) + surface.AttributeOff(A_REVERSE); + } + } + + void DrawContent(Surface &surface) { + Rect content_bounds = surface.GetFrame(); + Rect text_field_bounds, matchs_bounds; + content_bounds.HorizontalSplit(m_text_field.FieldDelegateGetHeight(), + text_field_bounds, matchs_bounds); + Surface text_field_surface = surface.SubSurface(text_field_bounds); + Surface matches_surface = surface.SubSurface(matchs_bounds); + + m_text_field.FieldDelegateDraw(text_field_surface, true); + DrawMatches(matches_surface); + } + + bool WindowDelegateDraw(Window &window, bool force) override { + window.Erase(); + + window.DrawTitleBox(window.GetName(), "Press Esc to Cancel"); + + Rect content_bounds = window.GetFrame(); + content_bounds.Inset(2, 2); + Surface content_surface = window.SubSurface(content_bounds); + + DrawContent(content_surface); + return true; + } + + void SelectNext() { + if (m_selected_match != m_delegate_sp->GetNumberOfMatches() - 1) + m_selected_match++; + return; + } + + void SelectPrevious() { + if (m_selected_match != 0) + m_selected_match--; + return; + } + + void ExecuteCallback(Window &window) { + m_delegate_sp->ExecuteCallback(m_selected_match); + window.GetParent()->RemoveSubWindow(&window); + } + + void UpdateMatches() { + m_delegate_sp->UpdateMatches(m_text_field.GetText()); + m_selected_match = 0; + } + + HandleCharResult WindowDelegateHandleChar(Window &window, int key) override { + switch (key) { + case '\r': + case '\n': + case KEY_ENTER: + ExecuteCallback(window); + return eKeyHandled; + case '\t': + case KEY_DOWN: + SelectNext(); + return eKeyHandled; + case KEY_SHIFT_TAB: + case KEY_UP: + SelectPrevious(); + return eKeyHandled; + case KEY_ESCAPE: + window.GetParent()->RemoveSubWindow(&window); + return eKeyHandled; + default: + break; + } + + if (m_text_field.FieldDelegateHandleChar(key) == eKeyHandled) + UpdateMatches(); + + return eKeyHandled; + } + +protected: + SearcherDelegateSP m_delegate_sp; + TextFieldDelegate m_text_field; + // The index of the currently selected match. + int m_selected_match; + // The index of the first visible match. + int m_first_visible_match; +}; + +////////////////////////////// +// Searcher Delegate Instances +////////////////////////////// + +// This is a searcher delegate wrapper around CommandCompletions common +// callbacks. The callbacks are only given the match string. The completion_mask +// can be a combination of CommonCompletionTypes. +class CommonCompletionSearcherDelegate : public SearcherDelegate { +public: + typedef std::function<void(const std::string &)> CallbackType; + + CommonCompletionSearcherDelegate(Debugger &debugger, uint32_t completion_mask, + CallbackType callback) + : m_debugger(debugger), m_completion_mask(completion_mask), + m_callback(callback) {} + + int GetNumberOfMatches() override { return m_matches.GetSize(); } + + const std::string &GetMatchTextAtIndex(int index) override { + return m_matches[index]; + } + + void UpdateMatches(const std::string &text) override { + CompletionResult result; + CompletionRequest request(text.c_str(), text.size(), result); + CommandCompletions::InvokeCommonCompletionCallbacks( + m_debugger.GetCommandInterpreter(), m_completion_mask, request, + nullptr); + result.GetMatches(m_matches); + } + + void ExecuteCallback(int match_index) override { + m_callback(m_matches[match_index]); + } + +protected: + Debugger &m_debugger; + // A compound mask from CommonCompletionTypes. + uint32_t m_completion_mask; + // A callback to execute once the user selects a match. The match is passed to + // the callback as a string. + CallbackType m_callback; + StringList m_matches; +}; + +//////// +// Menus +//////// + class MenuDelegate { public: virtual ~MenuDelegate() = default; @@ -3078,15 +4297,15 @@ public: bool done = false; int delay_in_tenths_of_a_second = 1; - // Alas the threading model in curses is a bit lame so we need to resort to - // polling every 0.5 seconds. We could poll for stdin ourselves and then - // pass the keys down but then we need to translate all of the escape + // Alas the threading model in curses is a bit lame so we need to resort + // to polling every 0.5 seconds. We could poll for stdin ourselves and + // then pass the keys down but then we need to translate all of the escape // sequences ourselves. So we resort to polling for input because we need // to receive async process events while in this loop. - halfdelay(delay_in_tenths_of_a_second); // Poll using some number of tenths - // of seconds seconds when calling - // Window::GetChar() + halfdelay(delay_in_tenths_of_a_second); // Poll using some number of + // tenths of seconds seconds when + // calling Window::GetChar() ListenerSP listener_sp( Listener::MakeListener("lldb.IOHandler.curses.Application")); @@ -3392,9 +4611,14 @@ public: TreeItem *&selected_item) { return; } - virtual bool TreeDelegateItemSelected( - TreeItem &item) = 0; // Return true if we need to update views + // This is invoked when a tree item is selected. If true is returned, the + // views are updated. + virtual bool TreeDelegateItemSelected(TreeItem &item) = 0; virtual bool TreeDelegateExpandRootByDefault() { return false; } + // This is mostly useful for root tree delegates. If false is returned, + // drawing will be skipped completely. This is needed, for instance, in + // skipping drawing of the threads tree if there is no running process. + virtual bool TreeDelegateShouldDraw() { return true; } }; typedef std::shared_ptr<TreeDelegate> TreeDelegateSP; @@ -3584,6 +4808,16 @@ public: void SetIdentifier(uint64_t identifier) { m_identifier = identifier; } + const std::string &GetText() const { return m_text; } + + void SetText(const char *text) { + if (text == nullptr) { + m_text.clear(); + return; + } + m_text = text; + } + void SetMightHaveChildren(bool b) { m_might_have_children = b; } protected: @@ -3591,6 +4825,7 @@ protected: TreeDelegate &m_delegate; void *m_user_data; uint64_t m_identifier; + std::string m_text; int m_row_idx; // Zero based visible row index, -1 if not visible or for the // root item std::vector<TreeItem> m_children; @@ -3609,21 +4844,6 @@ public: int NumVisibleRows() const { return m_max_y - m_min_y; } bool WindowDelegateDraw(Window &window, bool force) override { - ExecutionContext exe_ctx( - m_debugger.GetCommandInterpreter().GetExecutionContext()); - Process *process = exe_ctx.GetProcessPtr(); - - bool display_content = false; - if (process) { - StateType state = process->GetState(); - if (StateIsStoppedState(state, true)) { - // We are stopped, so it is ok to - display_content = true; - } else if (StateIsRunningState(state)) { - return true; // Don't do any updating when we are running - } - } - m_min_x = 2; m_min_y = 1; m_max_x = window.GetWidth() - 1; @@ -3632,35 +4852,36 @@ public: window.Erase(); window.DrawTitleBox(window.GetName()); - if (display_content) { - const int num_visible_rows = NumVisibleRows(); - m_num_rows = 0; - m_root.CalculateRowIndexes(m_num_rows); - m_delegate_sp->TreeDelegateUpdateSelection(m_root, m_selected_row_idx, - m_selected_item); - - // If we unexpanded while having something selected our total number of - // rows is less than the num visible rows, then make sure we show all the - // rows by setting the first visible row accordingly. - if (m_first_visible_row > 0 && m_num_rows < num_visible_rows) - m_first_visible_row = 0; - - // Make sure the selected row is always visible - if (m_selected_row_idx < m_first_visible_row) - m_first_visible_row = m_selected_row_idx; - else if (m_first_visible_row + num_visible_rows <= m_selected_row_idx) - m_first_visible_row = m_selected_row_idx - num_visible_rows + 1; - - int row_idx = 0; - int num_rows_left = num_visible_rows; - m_root.Draw(window, m_first_visible_row, m_selected_row_idx, row_idx, - num_rows_left); - // Get the selected row - m_selected_item = m_root.GetItemForRowIndex(m_selected_row_idx); - } else { + if (!m_delegate_sp->TreeDelegateShouldDraw()) { m_selected_item = nullptr; + return true; } + const int num_visible_rows = NumVisibleRows(); + m_num_rows = 0; + m_root.CalculateRowIndexes(m_num_rows); + m_delegate_sp->TreeDelegateUpdateSelection(m_root, m_selected_row_idx, + m_selected_item); + + // If we unexpanded while having something selected our total number of + // rows is less than the num visible rows, then make sure we show all the + // rows by setting the first visible row accordingly. + if (m_first_visible_row > 0 && m_num_rows < num_visible_rows) + m_first_visible_row = 0; + + // Make sure the selected row is always visible + if (m_selected_row_idx < m_first_visible_row) + m_first_visible_row = m_selected_row_idx; + else if (m_first_visible_row + num_visible_rows <= m_selected_row_idx) + m_first_visible_row = m_selected_row_idx - num_visible_rows + 1; + + int row_idx = 0; + int num_rows_left = num_visible_rows; + m_root.Draw(window, m_first_visible_row, m_selected_row_idx, row_idx, + num_rows_left); + // Get the selected row + m_selected_item = m_root.GetItemForRowIndex(m_selected_row_idx); + return true; // Drawing handled } @@ -3788,6 +5009,23 @@ protected: int m_max_y; }; +// A tree delegate that just draws the text member of the tree item, it doesn't +// have any children or actions. +class TextTreeDelegate : public TreeDelegate { +public: + TextTreeDelegate() : TreeDelegate() {} + + ~TextTreeDelegate() override = default; + + void TreeDelegateDrawTreeItem(TreeItem &item, Window &window) override { + window.PutCStringTruncated(1, item.GetText().c_str()); + } + + void TreeDelegateGenerateChildren(TreeItem &item) override {} + + bool TreeDelegateItemSelected(TreeItem &item) override { return false; } +}; + class FrameTreeDelegate : public TreeDelegate { public: FrameTreeDelegate() : TreeDelegate() { @@ -3952,6 +5190,17 @@ public: .GetProcessSP(); } + bool TreeDelegateShouldDraw() override { + ProcessSP process = GetProcess(); + if (!process) + return false; + + if (StateIsRunningState(process->GetState())) + return false; + + return true; + } + void TreeDelegateDrawTreeItem(TreeItem &item, Window &window) override { ProcessSP process_sp = GetProcess(); if (process_sp && process_sp->IsAlive()) { @@ -4043,6 +5292,240 @@ protected: FormatEntity::Entry m_format; }; +class BreakpointLocationTreeDelegate : public TreeDelegate { +public: + BreakpointLocationTreeDelegate(Debugger &debugger) + : TreeDelegate(), m_debugger(debugger) {} + + ~BreakpointLocationTreeDelegate() override = default; + + Process *GetProcess() { + ExecutionContext exe_ctx( + m_debugger.GetCommandInterpreter().GetExecutionContext()); + return exe_ctx.GetProcessPtr(); + } + + BreakpointLocationSP GetBreakpointLocation(const TreeItem &item) { + Breakpoint *breakpoint = (Breakpoint *)item.GetUserData(); + return breakpoint->GetLocationAtIndex(item.GetIdentifier()); + } + + void TreeDelegateDrawTreeItem(TreeItem &item, Window &window) override { + BreakpointLocationSP breakpoint_location = GetBreakpointLocation(item); + Process *process = GetProcess(); + StreamString stream; + stream.Printf("%i.%i: ", breakpoint_location->GetBreakpoint().GetID(), + breakpoint_location->GetID()); + Address address = breakpoint_location->GetAddress(); + address.Dump(&stream, process, Address::DumpStyleResolvedDescription, + Address::DumpStyleInvalid); + window.PutCStringTruncated(1, stream.GetString().str().c_str()); + } + + StringList ComputeDetailsList(BreakpointLocationSP breakpoint_location) { + StringList details; + + Address address = breakpoint_location->GetAddress(); + SymbolContext symbol_context; + address.CalculateSymbolContext(&symbol_context); + + if (symbol_context.module_sp) { + StreamString module_stream; + module_stream.PutCString("module = "); + symbol_context.module_sp->GetFileSpec().Dump( + module_stream.AsRawOstream()); + details.AppendString(module_stream.GetString()); + } + + if (symbol_context.comp_unit != nullptr) { + StreamString compile_unit_stream; + compile_unit_stream.PutCString("compile unit = "); + symbol_context.comp_unit->GetPrimaryFile().GetFilename().Dump( + &compile_unit_stream); + details.AppendString(compile_unit_stream.GetString()); + + if (symbol_context.function != nullptr) { + StreamString function_stream; + function_stream.PutCString("function = "); + function_stream.PutCString( + symbol_context.function->GetName().AsCString("<unknown>")); + details.AppendString(function_stream.GetString()); + } + + if (symbol_context.line_entry.line > 0) { + StreamString location_stream; + location_stream.PutCString("location = "); + symbol_context.line_entry.DumpStopContext(&location_stream, true); + details.AppendString(location_stream.GetString()); + } + + } else { + if (symbol_context.symbol) { + StreamString symbol_stream; + if (breakpoint_location->IsReExported()) + symbol_stream.PutCString("re-exported target = "); + else + symbol_stream.PutCString("symbol = "); + symbol_stream.PutCString( + symbol_context.symbol->GetName().AsCString("<unknown>")); + details.AppendString(symbol_stream.GetString()); + } + } + + Process *process = GetProcess(); + + StreamString address_stream; + address.Dump(&address_stream, process, Address::DumpStyleLoadAddress, + Address::DumpStyleModuleWithFileAddress); + details.AppendString(address_stream.GetString()); + + BreakpointSiteSP breakpoint_site = breakpoint_location->GetBreakpointSite(); + if (breakpoint_location->IsIndirect() && breakpoint_site) { + Address resolved_address; + resolved_address.SetLoadAddress(breakpoint_site->GetLoadAddress(), + &breakpoint_location->GetTarget()); + Symbol *resolved_symbol = resolved_address.CalculateSymbolContextSymbol(); + if (resolved_symbol) { + StreamString indirect_target_stream; + indirect_target_stream.PutCString("indirect target = "); + indirect_target_stream.PutCString( + resolved_symbol->GetName().GetCString()); + details.AppendString(indirect_target_stream.GetString()); + } + } + + bool is_resolved = breakpoint_location->IsResolved(); + StreamString resolved_stream; + resolved_stream.Printf("resolved = %s", is_resolved ? "true" : "false"); + details.AppendString(resolved_stream.GetString()); + + bool is_hardware = is_resolved && breakpoint_site->IsHardware(); + StreamString hardware_stream; + hardware_stream.Printf("hardware = %s", is_hardware ? "true" : "false"); + details.AppendString(hardware_stream.GetString()); + + StreamString hit_count_stream; + hit_count_stream.Printf("hit count = %-4u", + breakpoint_location->GetHitCount()); + details.AppendString(hit_count_stream.GetString()); + + return details; + } + + void TreeDelegateGenerateChildren(TreeItem &item) override { + BreakpointLocationSP breakpoint_location = GetBreakpointLocation(item); + StringList details = ComputeDetailsList(breakpoint_location); + + if (!m_string_delegate_sp) + m_string_delegate_sp = std::make_shared<TextTreeDelegate>(); + TreeItem details_tree_item(&item, *m_string_delegate_sp, false); + + item.Resize(details.GetSize(), details_tree_item); + for (size_t i = 0; i < details.GetSize(); i++) { + item[i].SetText(details.GetStringAtIndex(i)); + } + } + + bool TreeDelegateItemSelected(TreeItem &item) override { return false; } + +protected: + Debugger &m_debugger; + std::shared_ptr<TextTreeDelegate> m_string_delegate_sp; +}; + +class BreakpointTreeDelegate : public TreeDelegate { +public: + BreakpointTreeDelegate(Debugger &debugger) + : TreeDelegate(), m_debugger(debugger), + m_breakpoint_location_delegate_sp() {} + + ~BreakpointTreeDelegate() override = default; + + BreakpointSP GetBreakpoint(const TreeItem &item) { + TargetSP target = m_debugger.GetSelectedTarget(); + BreakpointList &breakpoints = target->GetBreakpointList(false); + return breakpoints.GetBreakpointAtIndex(item.GetIdentifier()); + } + + void TreeDelegateDrawTreeItem(TreeItem &item, Window &window) override { + BreakpointSP breakpoint = GetBreakpoint(item); + StreamString stream; + stream.Format("{0}: ", breakpoint->GetID()); + breakpoint->GetResolverDescription(&stream); + breakpoint->GetFilterDescription(&stream); + window.PutCStringTruncated(1, stream.GetString().str().c_str()); + } + + void TreeDelegateGenerateChildren(TreeItem &item) override { + BreakpointSP breakpoint = GetBreakpoint(item); + + if (!m_breakpoint_location_delegate_sp) + m_breakpoint_location_delegate_sp = + std::make_shared<BreakpointLocationTreeDelegate>(m_debugger); + TreeItem breakpoint_location_tree_item( + &item, *m_breakpoint_location_delegate_sp, true); + + item.Resize(breakpoint->GetNumLocations(), breakpoint_location_tree_item); + for (size_t i = 0; i < breakpoint->GetNumLocations(); i++) { + item[i].SetIdentifier(i); + item[i].SetUserData(breakpoint.get()); + } + } + + bool TreeDelegateItemSelected(TreeItem &item) override { return false; } + +protected: + Debugger &m_debugger; + std::shared_ptr<BreakpointLocationTreeDelegate> + m_breakpoint_location_delegate_sp; +}; + +class BreakpointsTreeDelegate : public TreeDelegate { +public: + BreakpointsTreeDelegate(Debugger &debugger) + : TreeDelegate(), m_debugger(debugger), m_breakpoint_delegate_sp() {} + + ~BreakpointsTreeDelegate() override = default; + + bool TreeDelegateShouldDraw() override { + TargetSP target = m_debugger.GetSelectedTarget(); + if (!target) + return false; + + return true; + } + + void TreeDelegateDrawTreeItem(TreeItem &item, Window &window) override { + window.PutCString("Breakpoints"); + } + + void TreeDelegateGenerateChildren(TreeItem &item) override { + TargetSP target = m_debugger.GetSelectedTarget(); + + BreakpointList &breakpoints = target->GetBreakpointList(false); + std::unique_lock<std::recursive_mutex> lock; + breakpoints.GetListMutex(lock); + + if (!m_breakpoint_delegate_sp) + m_breakpoint_delegate_sp = + std::make_shared<BreakpointTreeDelegate>(m_debugger); + TreeItem breakpoint_tree_item(&item, *m_breakpoint_delegate_sp, true); + + item.Resize(breakpoints.GetSize(), breakpoint_tree_item); + for (size_t i = 0; i < breakpoints.GetSize(); i++) { + item[i].SetIdentifier(i); + } + } + + bool TreeDelegateItemSelected(TreeItem &item) override { return false; } + + bool TreeDelegateExpandRootByDefault() override { return true; } + +protected: + Debugger &m_debugger; + std::shared_ptr<BreakpointTreeDelegate> m_breakpoint_delegate_sp; +}; + class ValueObjectListDelegate : public WindowDelegate { public: ValueObjectListDelegate() : m_rows() {} @@ -4844,6 +6327,7 @@ public: eMenuID_ViewRegisters, eMenuID_ViewSource, eMenuID_ViewVariables, + eMenuID_ViewBreakpoints, eMenuID_Help, eMenuID_HelpGUIHelp @@ -4908,6 +6392,18 @@ public: MenuActionResult MenuDelegateAction(Menu &menu) override { switch (menu.GetIdentifier()) { + case eMenuID_TargetCreate: { + WindowSP main_window_sp = m_app.GetMainWindow(); + FormDelegateSP form_delegate_sp = + FormDelegateSP(new TargetCreateFormDelegate(m_debugger)); + Rect bounds = main_window_sp->GetCenteredRect(80, 19); + WindowSP form_window_sp = main_window_sp->CreateSubWindow( + form_delegate_sp->GetName().c_str(), bounds, true); + WindowDelegateSP window_delegate_sp = + WindowDelegateSP(new FormWindowDelegate(form_delegate_sp)); + form_window_sp->SetDelegate(window_delegate_sp); + return MenuActionResult::Handled; + } case eMenuID_ThreadStepIn: { ExecutionContext exe_ctx = m_debugger.GetCommandInterpreter().GetExecutionContext(); @@ -4956,6 +6452,18 @@ public: form_window_sp->SetDelegate(window_delegate_sp); return MenuActionResult::Handled; } + case eMenuID_ProcessLaunch: { + WindowSP main_window_sp = m_app.GetMainWindow(); + FormDelegateSP form_delegate_sp = FormDelegateSP( + new ProcessLaunchFormDelegate(m_debugger, main_window_sp)); + Rect bounds = main_window_sp->GetCenteredRect(80, 22); + WindowSP form_window_sp = main_window_sp->CreateSubWindow( + form_delegate_sp->GetName().c_str(), bounds, true); + WindowDelegateSP window_delegate_sp = + WindowDelegateSP(new FormWindowDelegate(form_delegate_sp)); + form_window_sp->SetDelegate(window_delegate_sp); + return MenuActionResult::Handled; + } case eMenuID_ProcessContinue: { ExecutionContext exe_ctx = @@ -5046,8 +6554,8 @@ public: // previously added submenus.erase(submenus.begin() + 7, submenus.end()); } - // Since we are adding and removing items we need to recalculate the name - // lengths + // Since we are adding and removing items we need to recalculate the + // name lengths menu.RecalculateNameLengths(); } return MenuActionResult::Handled; @@ -5155,6 +6663,39 @@ public: } return MenuActionResult::Handled; + case eMenuID_ViewBreakpoints: { + WindowSP main_window_sp = m_app.GetMainWindow(); + WindowSP threads_window_sp = main_window_sp->FindSubWindow("Threads"); + WindowSP breakpoints_window_sp = + main_window_sp->FindSubWindow("Breakpoints"); + const Rect threads_bounds = threads_window_sp->GetBounds(); + + // If a breakpoints window already exists, remove it and give the area + // it used to occupy to the threads window. If it doesn't exist, split + // the threads window horizontally into two windows where the top window + // is the threads window and the bottom window is a newly added + // breakpoints window. + if (breakpoints_window_sp) { + threads_window_sp->Resize(threads_bounds.size.width, + threads_bounds.size.height + + breakpoints_window_sp->GetHeight()); + main_window_sp->RemoveSubWindow(breakpoints_window_sp.get()); + } else { + Rect new_threads_bounds, breakpoints_bounds; + threads_bounds.HorizontalSplitPercentage(0.70, new_threads_bounds, + breakpoints_bounds); + threads_window_sp->SetBounds(new_threads_bounds); + breakpoints_window_sp = main_window_sp->CreateSubWindow( + "Breakpoints", breakpoints_bounds, false); + TreeDelegateSP breakpoints_delegate_sp( + new BreakpointsTreeDelegate(m_debugger)); + breakpoints_window_sp->SetDelegate(WindowDelegateSP( + new TreeWindowDelegate(m_debugger, breakpoints_delegate_sp))); + } + touchwin(stdscr); + return MenuActionResult::Handled; + } + case eMenuID_HelpGUIHelp: m_app.GetMainWindow()->CreateHelpSubwindow(); return MenuActionResult::Handled; @@ -5347,8 +6888,8 @@ public: m_selected_line = m_pc_line; if (m_file_sp && m_file_sp->GetFileSpec() == m_sc.line_entry.file) { - // Same file, nothing to do, we should either have the lines or not - // (source file missing) + // Same file, nothing to do, we should either have the lines or + // not (source file missing) if (m_selected_line >= static_cast<size_t>(m_first_visible_line)) { if (m_selected_line >= m_first_visible_line + num_visible_lines) m_first_visible_line = m_selected_line - 10; @@ -5470,8 +7011,8 @@ public: window.MoveCursor(1, line_y); const bool is_pc_line = curr_line == m_pc_line; const bool line_is_selected = m_selected_line == curr_line; - // Highlight the line as the PC line first, then if the selected line - // isn't the same as the PC line, highlight it differently + // Highlight the line as the PC line first, then if the selected + // line isn't the same as the PC line, highlight it differently attr_t highlight_attr = 0; attr_t bp_attr = 0; if (is_pc_line) @@ -5610,8 +7151,8 @@ public: window.MoveCursor(1, line_y); const bool is_pc_line = frame_sp && inst_idx == pc_idx; const bool line_is_selected = m_selected_line == inst_idx; - // Highlight the line as the PC line first, then if the selected line - // isn't the same as the PC line, highlight it differently + // Highlight the line as the PC line first, then if the selected + // line isn't the same as the PC line, highlight it differently attr_t highlight_attr = 0; attr_t bp_attr = 0; if (is_pc_line) @@ -6075,7 +7616,7 @@ void IOHandlerCursesGUI::Activate() { MenuSP view_menu_sp( new Menu("View", "F5", KEY_F(5), ApplicationDelegate::eMenuID_View)); view_menu_sp->AddSubmenu( - MenuSP(new Menu("Backtrace", nullptr, 'b', + MenuSP(new Menu("Backtrace", nullptr, 't', ApplicationDelegate::eMenuID_ViewBacktrace))); view_menu_sp->AddSubmenu( MenuSP(new Menu("Registers", nullptr, 'r', @@ -6085,6 +7626,9 @@ void IOHandlerCursesGUI::Activate() { view_menu_sp->AddSubmenu( MenuSP(new Menu("Variables", nullptr, 'v', ApplicationDelegate::eMenuID_ViewVariables))); + view_menu_sp->AddSubmenu( + MenuSP(new Menu("Breakpoints", nullptr, 'b', + ApplicationDelegate::eMenuID_ViewBreakpoints))); MenuSP help_menu_sp( new Menu("Help", "F6", KEY_F(6), ApplicationDelegate::eMenuID_Help)); @@ -6145,7 +7689,8 @@ void IOHandlerCursesGUI::Activate() { status_window_sp->SetDelegate( WindowDelegateSP(new StatusBarWindowDelegate(m_debugger))); - // Show the main help window once the first time the curses GUI is launched + // Show the main help window once the first time the curses GUI is + // launched static bool g_showed_help = false; if (!g_showed_help) { g_showed_help = true; @@ -6176,6 +7721,7 @@ void IOHandlerCursesGUI::Activate() { static_assert(LastColorPairIndex == 18, "Color indexes do not match."); define_key("\033[Z", KEY_SHIFT_TAB); + define_key("\033\015", KEY_ALT_ENTER); } } diff --git a/contrib/llvm-project/lldb/source/Core/Mangled.cpp b/contrib/llvm-project/lldb/source/Core/Mangled.cpp index fbaf9ff7151a..20f4dbdb419f 100644 --- a/contrib/llvm-project/lldb/source/Core/Mangled.cpp +++ b/contrib/llvm-project/lldb/source/Core/Mangled.cpp @@ -9,6 +9,7 @@ #include "lldb/Core/Mangled.h" #include "lldb/Core/RichManglingContext.h" +#include "lldb/Target/Language.h" #include "lldb/Utility/ConstString.h" #include "lldb/Utility/Log.h" #include "lldb/Utility/Logging.h" @@ -16,8 +17,6 @@ #include "lldb/Utility/Stream.h" #include "lldb/lldb-enumerations.h" -#include "Plugins/Language/CPlusPlus/CPlusPlusLanguage.h" - #include "llvm/ADT/StringRef.h" #include "llvm/Demangle/Demangle.h" #include "llvm/Support/Compiler.h" @@ -34,35 +33,6 @@ static inline bool cstring_is_mangled(llvm::StringRef s) { return Mangled::GetManglingScheme(s) != Mangled::eManglingSchemeNone; } -static ConstString GetDemangledNameWithoutArguments(ConstString mangled, - ConstString demangled) { - const char *mangled_name_cstr = mangled.GetCString(); - - if (demangled && mangled_name_cstr && mangled_name_cstr[0]) { - if (mangled_name_cstr[0] == '_' && mangled_name_cstr[1] == 'Z' && - (mangled_name_cstr[2] != 'T' && // avoid virtual table, VTT structure, - // typeinfo structure, and typeinfo - // mangled_name - mangled_name_cstr[2] != 'G' && // avoid guard variables - mangled_name_cstr[2] != 'Z')) // named local entities (if we eventually - // handle eSymbolTypeData, we will want - // this back) - { - CPlusPlusLanguage::MethodName cxx_method(demangled); - if (!cxx_method.GetBasename().empty()) { - std::string shortname; - if (!cxx_method.GetContext().empty()) - shortname = cxx_method.GetContext().str() + "::"; - shortname += cxx_method.GetBasename().str(); - return ConstString(shortname); - } - } - } - if (demangled) - return demangled; - return mangled; -} - #pragma mark Mangled Mangled::ManglingScheme Mangled::GetManglingScheme(llvm::StringRef const name) { @@ -75,6 +45,9 @@ Mangled::ManglingScheme Mangled::GetManglingScheme(llvm::StringRef const name) { if (name.startswith("_R")) return Mangled::eManglingSchemeRustV0; + if (name.startswith("_D")) + return Mangled::eManglingSchemeD; + if (name.startswith("_Z")) return Mangled::eManglingSchemeItanium; @@ -161,9 +134,9 @@ void Mangled::SetValue(ConstString name) { static char *GetMSVCDemangledStr(const char *M) { char *demangled_cstr = llvm::microsoftDemangle( M, nullptr, nullptr, nullptr, nullptr, - llvm::MSDemangleFlags(llvm::MSDF_NoAccessSpecifier | - llvm::MSDF_NoCallingConvention | - llvm::MSDF_NoMemberType)); + llvm::MSDemangleFlags( + llvm::MSDF_NoAccessSpecifier | llvm::MSDF_NoCallingConvention | + llvm::MSDF_NoMemberType | llvm::MSDF_NoVariableType)); if (Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_DEMANGLE)) { if (demangled_cstr && demangled_cstr[0]) @@ -215,6 +188,19 @@ static char *GetRustV0DemangledStr(const char *M) { return demangled_cstr; } +static char *GetDLangDemangledStr(const char *M) { + char *demangled_cstr = llvm::dlangDemangle(M); + + if (Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_DEMANGLE)) { + if (demangled_cstr && demangled_cstr[0]) + LLDB_LOG(log, "demangled dlang: {0} -> \"{1}\"", M, demangled_cstr); + else + LLDB_LOG(log, "demangled dlang: {0} -> error: failed to demangle", M); + } + + return demangled_cstr; +} + // Explicit demangling for scheduled requests during batch processing. This // makes use of ItaniumPartialDemangler's rich demangle info bool Mangled::DemangleWithRichManglingInfo( @@ -274,7 +260,8 @@ bool Mangled::DemangleWithRichManglingInfo( } case eManglingSchemeRustV0: - // Rich demangling scheme is not supported for Rust + case eManglingSchemeD: + // Rich demangling scheme is not supported return false; } llvm_unreachable("Fully covered switch above!"); @@ -290,7 +277,8 @@ ConstString Mangled::GetDemangledName() const { if (m_mangled && m_demangled.IsNull()) { // Don't bother running anything that isn't mangled const char *mangled_name = m_mangled.GetCString(); - ManglingScheme mangling_scheme = GetManglingScheme(m_mangled.GetStringRef()); + ManglingScheme mangling_scheme = + GetManglingScheme(m_mangled.GetStringRef()); if (mangling_scheme != eManglingSchemeNone && !m_mangled.GetMangledCounterpart(m_demangled)) { // We didn't already mangle this name, demangle it and if all goes well @@ -307,6 +295,9 @@ ConstString Mangled::GetDemangledName() const { case eManglingSchemeRustV0: demangled_name = GetRustV0DemangledStr(mangled_name); break; + case eManglingSchemeD: + demangled_name = GetDLangDemangledStr(mangled_name); + break; case eManglingSchemeNone: llvm_unreachable("eManglingSchemeNone was handled already"); } @@ -326,8 +317,7 @@ ConstString Mangled::GetDemangledName() const { return m_demangled; } -ConstString -Mangled::GetDisplayDemangledName() const { +ConstString Mangled::GetDisplayDemangledName() const { return GetDemangledName(); } @@ -344,14 +334,16 @@ ConstString Mangled::GetName(Mangled::NamePreference preference) const { if (preference == ePreferMangled && m_mangled) return m_mangled; + // Call the accessor to make sure we get a demangled name in case it hasn't + // been demangled yet... ConstString demangled = GetDemangledName(); if (preference == ePreferDemangledWithoutArguments) { - return GetDemangledNameWithoutArguments(m_mangled, demangled); + if (Language *lang = Language::FindPlugin(GuessLanguage())) { + return lang->GetDemangledFunctionNameWithoutArguments(*this); + } } if (preference == ePreferDemangled) { - // Call the accessor to make sure we get a demangled name in case it hasn't - // been demangled yet... if (demangled) return demangled; return m_mangled; diff --git a/contrib/llvm-project/lldb/source/Core/Module.cpp b/contrib/llvm-project/lldb/source/Core/Module.cpp index 19c97be15066..bd0a667171a5 100644 --- a/contrib/llvm-project/lldb/source/Core/Module.cpp +++ b/contrib/llvm-project/lldb/source/Core/Module.cpp @@ -796,7 +796,7 @@ void Module::LookupInfo::Prune(SymbolContextList &sc_list, void Module::FindFunctions(ConstString name, const CompilerDeclContext &parent_decl_ctx, FunctionNameType name_type_mask, - bool include_symbols, bool include_inlines, + const ModuleFunctionSearchOptions &options, SymbolContextList &sc_list) { const size_t old_size = sc_list.GetSize(); @@ -808,12 +808,12 @@ void Module::FindFunctions(ConstString name, if (symbols) { symbols->FindFunctions(lookup_info.GetLookupName(), parent_decl_ctx, - lookup_info.GetNameTypeMask(), include_inlines, - sc_list); + lookup_info.GetNameTypeMask(), + options.include_inlines, sc_list); // Now check our symbol table for symbols that are code symbols if // requested - if (include_symbols) { + if (options.include_symbols) { Symtab *symtab = symbols->GetSymtab(); if (symtab) symtab->FindFunctionSymbols(lookup_info.GetLookupName(), @@ -828,11 +828,11 @@ void Module::FindFunctions(ConstString name, } else { if (symbols) { symbols->FindFunctions(name, parent_decl_ctx, name_type_mask, - include_inlines, sc_list); + options.include_inlines, sc_list); // Now check our symbol table for symbols that are code symbols if // requested - if (include_symbols) { + if (options.include_symbols) { Symtab *symtab = symbols->GetSymtab(); if (symtab) symtab->FindFunctionSymbols(name, name_type_mask, sc_list); @@ -841,17 +841,17 @@ void Module::FindFunctions(ConstString name, } } -void Module::FindFunctions(const RegularExpression ®ex, bool include_symbols, - bool include_inlines, +void Module::FindFunctions(const RegularExpression ®ex, + const ModuleFunctionSearchOptions &options, SymbolContextList &sc_list) { const size_t start_size = sc_list.GetSize(); if (SymbolFile *symbols = GetSymbolFile()) { - symbols->FindFunctions(regex, include_inlines, sc_list); + symbols->FindFunctions(regex, options.include_inlines, sc_list); // Now check our symbol table for symbols that are code symbols if // requested - if (include_symbols) { + if (options.include_symbols) { Symtab *symtab = symbols->GetSymtab(); if (symtab) { std::vector<uint32_t> symbol_indexes; @@ -1614,24 +1614,23 @@ llvm::Optional<std::string> Module::RemapSourceFile(llvm::StringRef path) const void Module::RegisterXcodeSDK(llvm::StringRef sdk_name, llvm::StringRef sysroot) { XcodeSDK sdk(sdk_name.str()); - ConstString sdk_path(HostInfo::GetXcodeSDKPath(sdk)); - if (!sdk_path) + llvm::StringRef sdk_path(HostInfo::GetXcodeSDKPath(sdk)); + if (sdk_path.empty()) return; // If the SDK changed for a previously registered source path, update it. // This could happend with -fdebug-prefix-map, otherwise it's unlikely. - ConstString sysroot_cs(sysroot); - if (!m_source_mappings.Replace(sysroot_cs, sdk_path, true)) + if (!m_source_mappings.Replace(sysroot, sdk_path, true)) // In the general case, however, append it to the list. - m_source_mappings.Append(sysroot_cs, sdk_path, false); + m_source_mappings.Append(sysroot, sdk_path, false); } bool Module::MergeArchitecture(const ArchSpec &arch_spec) { if (!arch_spec.IsValid()) return false; - LLDB_LOG(GetLogIfAllCategoriesSet(LIBLLDB_LOG_OBJECT | LIBLLDB_LOG_MODULES), - "module has arch %s, merging/replacing with arch %s", - m_arch.GetTriple().getTriple().c_str(), - arch_spec.GetTriple().getTriple().c_str()); + LLDB_LOGF(GetLogIfAllCategoriesSet(LIBLLDB_LOG_OBJECT | LIBLLDB_LOG_MODULES), + "module has arch %s, merging/replacing with arch %s", + m_arch.GetTriple().getTriple().c_str(), + arch_spec.GetTriple().getTriple().c_str()); if (!m_arch.IsCompatibleMatch(arch_spec)) { // The new architecture is different, we just need to replace it. return SetArchitecture(arch_spec); diff --git a/contrib/llvm-project/lldb/source/Core/ModuleList.cpp b/contrib/llvm-project/lldb/source/Core/ModuleList.cpp index 56bc4c72d8e9..9176c9dbb357 100644 --- a/contrib/llvm-project/lldb/source/Core/ModuleList.cpp +++ b/contrib/llvm-project/lldb/source/Core/ModuleList.cpp @@ -122,8 +122,7 @@ void ModuleListProperties::UpdateSymlinkMappings() { FileSpec resolved; Status status = FileSystem::Instance().Readlink(symlink, resolved); if (status.Success()) - m_symlink_paths.Append(ConstString(symlink.GetPath()), - ConstString(resolved.GetPath()), notify); + m_symlink_paths.Append(symlink.GetPath(), resolved.GetPath(), notify); } } @@ -200,16 +199,15 @@ void ModuleList::ReplaceEquivalent( } } -bool ModuleList::AppendIfNeeded(const ModuleSP &module_sp, bool notify) { - if (module_sp) { +bool ModuleList::AppendIfNeeded(const ModuleSP &new_module, bool notify) { + if (new_module) { std::lock_guard<std::recursive_mutex> guard(m_modules_mutex); - collection::iterator pos, end = m_modules.end(); - for (pos = m_modules.begin(); pos != end; ++pos) { - if (pos->get() == module_sp.get()) + for (const ModuleSP &module_sp : m_modules) { + if (module_sp.get() == new_module.get()) return false; // Already in the list } // Only push module_sp on the list if it wasn't already in there. - Append(module_sp, notify); + Append(new_module, notify); return true; } return false; @@ -364,7 +362,7 @@ ModuleSP ModuleList::GetModuleAtIndexUnlocked(size_t idx) const { void ModuleList::FindFunctions(ConstString name, FunctionNameType name_type_mask, - bool include_symbols, bool include_inlines, + const ModuleFunctionSearchOptions &options, SymbolContextList &sc_list) const { const size_t old_size = sc_list.GetSize(); @@ -372,11 +370,10 @@ void ModuleList::FindFunctions(ConstString name, Module::LookupInfo lookup_info(name, name_type_mask, eLanguageTypeUnknown); std::lock_guard<std::recursive_mutex> guard(m_modules_mutex); - collection::const_iterator pos, end = m_modules.end(); - for (pos = m_modules.begin(); pos != end; ++pos) { - (*pos)->FindFunctions(lookup_info.GetLookupName(), CompilerDeclContext(), - lookup_info.GetNameTypeMask(), include_symbols, - include_inlines, sc_list); + for (const ModuleSP &module_sp : m_modules) { + module_sp->FindFunctions(lookup_info.GetLookupName(), + CompilerDeclContext(), + lookup_info.GetNameTypeMask(), options, sc_list); } const size_t new_size = sc_list.GetSize(); @@ -385,10 +382,9 @@ void ModuleList::FindFunctions(ConstString name, lookup_info.Prune(sc_list, old_size); } else { std::lock_guard<std::recursive_mutex> guard(m_modules_mutex); - collection::const_iterator pos, end = m_modules.end(); - for (pos = m_modules.begin(); pos != end; ++pos) { - (*pos)->FindFunctions(name, CompilerDeclContext(), name_type_mask, - include_symbols, include_inlines, sc_list); + for (const ModuleSP &module_sp : m_modules) { + module_sp->FindFunctions(name, CompilerDeclContext(), name_type_mask, + options, sc_list); } } } @@ -402,10 +398,9 @@ void ModuleList::FindFunctionSymbols(ConstString name, Module::LookupInfo lookup_info(name, name_type_mask, eLanguageTypeUnknown); std::lock_guard<std::recursive_mutex> guard(m_modules_mutex); - collection::const_iterator pos, end = m_modules.end(); - for (pos = m_modules.begin(); pos != end; ++pos) { - (*pos)->FindFunctionSymbols(lookup_info.GetLookupName(), - lookup_info.GetNameTypeMask(), sc_list); + for (const ModuleSP &module_sp : m_modules) { + module_sp->FindFunctionSymbols(lookup_info.GetLookupName(), + lookup_info.GetNameTypeMask(), sc_list); } const size_t new_size = sc_list.GetSize(); @@ -414,39 +409,33 @@ void ModuleList::FindFunctionSymbols(ConstString name, lookup_info.Prune(sc_list, old_size); } else { std::lock_guard<std::recursive_mutex> guard(m_modules_mutex); - collection::const_iterator pos, end = m_modules.end(); - for (pos = m_modules.begin(); pos != end; ++pos) { - (*pos)->FindFunctionSymbols(name, name_type_mask, sc_list); + for (const ModuleSP &module_sp : m_modules) { + module_sp->FindFunctionSymbols(name, name_type_mask, sc_list); } } } void ModuleList::FindFunctions(const RegularExpression &name, - bool include_symbols, bool include_inlines, + const ModuleFunctionSearchOptions &options, SymbolContextList &sc_list) { std::lock_guard<std::recursive_mutex> guard(m_modules_mutex); - collection::const_iterator pos, end = m_modules.end(); - for (pos = m_modules.begin(); pos != end; ++pos) { - (*pos)->FindFunctions(name, include_symbols, include_inlines, sc_list); - } + for (const ModuleSP &module_sp : m_modules) + module_sp->FindFunctions(name, options, sc_list); } void ModuleList::FindCompileUnits(const FileSpec &path, SymbolContextList &sc_list) const { std::lock_guard<std::recursive_mutex> guard(m_modules_mutex); - collection::const_iterator pos, end = m_modules.end(); - for (pos = m_modules.begin(); pos != end; ++pos) { - (*pos)->FindCompileUnits(path, sc_list); - } + for (const ModuleSP &module_sp : m_modules) + module_sp->FindCompileUnits(path, sc_list); } void ModuleList::FindGlobalVariables(ConstString name, size_t max_matches, VariableList &variable_list) const { std::lock_guard<std::recursive_mutex> guard(m_modules_mutex); - collection::const_iterator pos, end = m_modules.end(); - for (pos = m_modules.begin(); pos != end; ++pos) { - (*pos)->FindGlobalVariables(name, CompilerDeclContext(), max_matches, - variable_list); + for (const ModuleSP &module_sp : m_modules) { + module_sp->FindGlobalVariables(name, CompilerDeclContext(), max_matches, + variable_list); } } @@ -454,36 +443,30 @@ void ModuleList::FindGlobalVariables(const RegularExpression ®ex, size_t max_matches, VariableList &variable_list) const { std::lock_guard<std::recursive_mutex> guard(m_modules_mutex); - collection::const_iterator pos, end = m_modules.end(); - for (pos = m_modules.begin(); pos != end; ++pos) { - (*pos)->FindGlobalVariables(regex, max_matches, variable_list); - } + for (const ModuleSP &module_sp : m_modules) + module_sp->FindGlobalVariables(regex, max_matches, variable_list); } void ModuleList::FindSymbolsWithNameAndType(ConstString name, SymbolType symbol_type, SymbolContextList &sc_list) const { std::lock_guard<std::recursive_mutex> guard(m_modules_mutex); - collection::const_iterator pos, end = m_modules.end(); - for (pos = m_modules.begin(); pos != end; ++pos) - (*pos)->FindSymbolsWithNameAndType(name, symbol_type, sc_list); + for (const ModuleSP &module_sp : m_modules) + module_sp->FindSymbolsWithNameAndType(name, symbol_type, sc_list); } void ModuleList::FindSymbolsMatchingRegExAndType( const RegularExpression ®ex, lldb::SymbolType symbol_type, SymbolContextList &sc_list) const { std::lock_guard<std::recursive_mutex> guard(m_modules_mutex); - collection::const_iterator pos, end = m_modules.end(); - for (pos = m_modules.begin(); pos != end; ++pos) - (*pos)->FindSymbolsMatchingRegExAndType(regex, symbol_type, sc_list); + for (const ModuleSP &module_sp : m_modules) + module_sp->FindSymbolsMatchingRegExAndType(regex, symbol_type, sc_list); } void ModuleList::FindModules(const ModuleSpec &module_spec, ModuleList &matching_module_list) const { std::lock_guard<std::recursive_mutex> guard(m_modules_mutex); - collection::const_iterator pos, end = m_modules.end(); - for (pos = m_modules.begin(); pos != end; ++pos) { - ModuleSP module_sp(*pos); + for (const ModuleSP &module_sp : m_modules) { if (module_sp->MatchesModuleSpec(module_spec)) matching_module_list.Append(module_sp); } @@ -559,9 +542,8 @@ void ModuleList::FindTypes(Module *search_first, ConstString name, bool ModuleList::FindSourceFile(const FileSpec &orig_spec, FileSpec &new_spec) const { std::lock_guard<std::recursive_mutex> guard(m_modules_mutex); - collection::const_iterator pos, end = m_modules.end(); - for (pos = m_modules.begin(); pos != end; ++pos) { - if ((*pos)->FindSourceFile(orig_spec, new_spec)) + for (const ModuleSP &module_sp : m_modules) { + if (module_sp->FindSourceFile(orig_spec, new_spec)) return true; } return false; @@ -573,10 +555,9 @@ void ModuleList::FindAddressesForLine(const lldb::TargetSP target_sp, std::vector<Address> &output_local, std::vector<Address> &output_extern) { std::lock_guard<std::recursive_mutex> guard(m_modules_mutex); - collection::const_iterator pos, end = m_modules.end(); - for (pos = m_modules.begin(); pos != end; ++pos) { - (*pos)->FindAddressesForLine(target_sp, file, line, function, output_local, - output_extern); + for (const ModuleSP &module_sp : m_modules) { + module_sp->FindAddressesForLine(target_sp, file, line, function, + output_local, output_extern); } } @@ -603,10 +584,8 @@ size_t ModuleList::GetSize() const { void ModuleList::Dump(Stream *s) const { std::lock_guard<std::recursive_mutex> guard(m_modules_mutex); - collection::const_iterator pos, end = m_modules.end(); - for (pos = m_modules.begin(); pos != end; ++pos) { - (*pos)->Dump(s); - } + for (const ModuleSP &module_sp : m_modules) + module_sp->Dump(s); } void ModuleList::LogUUIDAndPaths(Log *log, const char *prefix_cstr) { @@ -629,9 +608,8 @@ void ModuleList::LogUUIDAndPaths(Log *log, const char *prefix_cstr) { bool ModuleList::ResolveFileAddress(lldb::addr_t vm_addr, Address &so_addr) const { std::lock_guard<std::recursive_mutex> guard(m_modules_mutex); - collection::const_iterator pos, end = m_modules.end(); - for (pos = m_modules.begin(); pos != end; ++pos) { - if ((*pos)->ResolveFileAddress(vm_addr, so_addr)) + for (const ModuleSP &module_sp : m_modules) { + if (module_sp->ResolveFileAddress(vm_addr, so_addr)) return true; } @@ -674,10 +652,9 @@ uint32_t ModuleList::ResolveSymbolContextsForFileSpec( const FileSpec &file_spec, uint32_t line, bool check_inlines, SymbolContextItem resolve_scope, SymbolContextList &sc_list) const { std::lock_guard<std::recursive_mutex> guard(m_modules_mutex); - collection::const_iterator pos, end = m_modules.end(); - for (pos = m_modules.begin(); pos != end; ++pos) { - (*pos)->ResolveSymbolContextsForFileSpec(file_spec, line, check_inlines, - resolve_scope, sc_list); + for (const ModuleSP &module_sp : m_modules) { + module_sp->ResolveSymbolContextsForFileSpec(file_spec, line, check_inlines, + resolve_scope, sc_list); } return sc_list.GetSize(); diff --git a/contrib/llvm-project/lldb/source/Core/PluginManager.cpp b/contrib/llvm-project/lldb/source/Core/PluginManager.cpp index fcaa868b083e..801591129244 100644 --- a/contrib/llvm-project/lldb/source/Core/PluginManager.cpp +++ b/contrib/llvm-project/lldb/source/Core/PluginManager.cpp @@ -12,6 +12,7 @@ #include "lldb/Host/FileSystem.h" #include "lldb/Host/HostInfo.h" #include "lldb/Interpreter/OptionValueProperties.h" +#include "lldb/Target/Process.h" #include "lldb/Utility/ConstString.h" #include "lldb/Utility/FileSpec.h" #include "lldb/Utility/Status.h" @@ -184,15 +185,14 @@ template <typename Callback> struct PluginInstance { typedef Callback CallbackType; PluginInstance() = default; - PluginInstance(ConstString name, std::string description, - Callback create_callback = nullptr, + PluginInstance(llvm::StringRef name, llvm::StringRef description, + Callback create_callback, DebuggerInitializeCallback debugger_init_callback = nullptr) - : name(name), description(std::move(description)), - create_callback(create_callback), + : name(name), description(description), create_callback(create_callback), debugger_init_callback(debugger_init_callback) {} - ConstString name; - std::string description; + llvm::StringRef name; + llvm::StringRef description; Callback create_callback; DebuggerInitializeCallback debugger_init_callback; }; @@ -200,12 +200,12 @@ template <typename Callback> struct PluginInstance { template <typename Instance> class PluginInstances { public: template <typename... Args> - bool RegisterPlugin(ConstString name, const char *description, + bool RegisterPlugin(llvm::StringRef name, llvm::StringRef description, typename Instance::CallbackType callback, - Args &&... args) { + Args &&...args) { if (!callback) return false; - assert((bool)name); + assert(!name.empty()); Instance instance = Instance(name, description, callback, std::forward<Args>(args)...); m_instances.push_back(instance); @@ -232,20 +232,20 @@ public: return nullptr; } - const char *GetDescriptionAtIndex(uint32_t idx) { + llvm::StringRef GetDescriptionAtIndex(uint32_t idx) { if (Instance *instance = GetInstanceAtIndex(idx)) - return instance->description.c_str(); - return nullptr; + return instance->description; + return ""; } - const char *GetNameAtIndex(uint32_t idx) { + llvm::StringRef GetNameAtIndex(uint32_t idx) { if (Instance *instance = GetInstanceAtIndex(idx)) - return instance->name.GetCString(); - return nullptr; + return instance->name; + return ""; } - typename Instance::CallbackType GetCallbackForName(ConstString name) { - if (!name) + typename Instance::CallbackType GetCallbackForName(llvm::StringRef name) { + if (name.empty()) return nullptr; for (auto &instance : m_instances) { if (name == instance.name) @@ -284,7 +284,8 @@ static ABIInstances &GetABIInstances() { return g_instances; } -bool PluginManager::RegisterPlugin(ConstString name, const char *description, +bool PluginManager::RegisterPlugin(llvm::StringRef name, + llvm::StringRef description, ABICreateInstance create_callback) { return GetABIInstances().RegisterPlugin(name, description, create_callback); } @@ -307,11 +308,10 @@ static ArchitectureInstances &GetArchitectureInstances() { return g_instances; } -void PluginManager::RegisterPlugin(ConstString name, +void PluginManager::RegisterPlugin(llvm::StringRef name, llvm::StringRef description, ArchitectureCreateInstance create_callback) { - GetArchitectureInstances().push_back( - {name, std::string(description), create_callback}); + GetArchitectureInstances().push_back({name, description, create_callback}); } void PluginManager::UnregisterPlugin( @@ -346,7 +346,8 @@ static DisassemblerInstances &GetDisassemblerInstances() { return g_instances; } -bool PluginManager::RegisterPlugin(ConstString name, const char *description, +bool PluginManager::RegisterPlugin(llvm::StringRef name, + llvm::StringRef description, DisassemblerCreateInstance create_callback) { return GetDisassemblerInstances().RegisterPlugin(name, description, create_callback); @@ -363,7 +364,8 @@ PluginManager::GetDisassemblerCreateCallbackAtIndex(uint32_t idx) { } DisassemblerCreateInstance -PluginManager::GetDisassemblerCreateCallbackForPluginName(ConstString name) { +PluginManager::GetDisassemblerCreateCallbackForPluginName( + llvm::StringRef name) { return GetDisassemblerInstances().GetCallbackForName(name); } @@ -378,7 +380,7 @@ static DynamicLoaderInstances &GetDynamicLoaderInstances() { } bool PluginManager::RegisterPlugin( - ConstString name, const char *description, + llvm::StringRef name, llvm::StringRef description, DynamicLoaderCreateInstance create_callback, DebuggerInitializeCallback debugger_init_callback) { return GetDynamicLoaderInstances().RegisterPlugin( @@ -396,7 +398,8 @@ PluginManager::GetDynamicLoaderCreateCallbackAtIndex(uint32_t idx) { } DynamicLoaderCreateInstance -PluginManager::GetDynamicLoaderCreateCallbackForPluginName(ConstString name) { +PluginManager::GetDynamicLoaderCreateCallbackForPluginName( + llvm::StringRef name) { return GetDynamicLoaderInstances().GetCallbackForName(name); } @@ -411,7 +414,7 @@ static JITLoaderInstances &GetJITLoaderInstances() { } bool PluginManager::RegisterPlugin( - ConstString name, const char *description, + llvm::StringRef name, llvm::StringRef description, JITLoaderCreateInstance create_callback, DebuggerInitializeCallback debugger_init_callback) { return GetJITLoaderInstances().RegisterPlugin( @@ -439,7 +442,7 @@ static EmulateInstructionInstances &GetEmulateInstructionInstances() { } bool PluginManager::RegisterPlugin( - ConstString name, const char *description, + llvm::StringRef name, llvm::StringRef description, EmulateInstructionCreateInstance create_callback) { return GetEmulateInstructionInstances().RegisterPlugin(name, description, create_callback); @@ -457,7 +460,7 @@ PluginManager::GetEmulateInstructionCreateCallbackAtIndex(uint32_t idx) { EmulateInstructionCreateInstance PluginManager::GetEmulateInstructionCreateCallbackForPluginName( - ConstString name) { + llvm::StringRef name) { return GetEmulateInstructionInstances().GetCallbackForName(name); } @@ -472,7 +475,7 @@ static OperatingSystemInstances &GetOperatingSystemInstances() { } bool PluginManager::RegisterPlugin( - ConstString name, const char *description, + llvm::StringRef name, llvm::StringRef description, OperatingSystemCreateInstance create_callback, DebuggerInitializeCallback debugger_init_callback) { return GetOperatingSystemInstances().RegisterPlugin( @@ -490,7 +493,8 @@ PluginManager::GetOperatingSystemCreateCallbackAtIndex(uint32_t idx) { } OperatingSystemCreateInstance -PluginManager::GetOperatingSystemCreateCallbackForPluginName(ConstString name) { +PluginManager::GetOperatingSystemCreateCallbackForPluginName( + llvm::StringRef name) { return GetOperatingSystemInstances().GetCallbackForName(name); } @@ -504,7 +508,8 @@ static LanguageInstances &GetLanguageInstances() { return g_instances; } -bool PluginManager::RegisterPlugin(ConstString name, const char *description, +bool PluginManager::RegisterPlugin(llvm::StringRef name, + llvm::StringRef description, LanguageCreateInstance create_callback) { return GetLanguageInstances().RegisterPlugin(name, description, create_callback); @@ -524,13 +529,13 @@ PluginManager::GetLanguageCreateCallbackAtIndex(uint32_t idx) { struct LanguageRuntimeInstance : public PluginInstance<LanguageRuntimeCreateInstance> { LanguageRuntimeInstance( - ConstString name, std::string description, CallbackType create_callback, + llvm::StringRef name, llvm::StringRef description, + CallbackType create_callback, DebuggerInitializeCallback debugger_init_callback, LanguageRuntimeGetCommandObject command_callback, LanguageRuntimeGetExceptionPrecondition precondition_callback) : PluginInstance<LanguageRuntimeCreateInstance>( - name, std::move(description), create_callback, - debugger_init_callback), + name, description, create_callback, debugger_init_callback), command_callback(command_callback), precondition_callback(precondition_callback) {} @@ -546,7 +551,7 @@ static LanguageRuntimeInstances &GetLanguageRuntimeInstances() { } bool PluginManager::RegisterPlugin( - ConstString name, const char *description, + llvm::StringRef name, llvm::StringRef description, LanguageRuntimeCreateInstance create_callback, LanguageRuntimeGetCommandObject command_callback, LanguageRuntimeGetExceptionPrecondition precondition_callback) { @@ -592,7 +597,7 @@ static SystemRuntimeInstances &GetSystemRuntimeInstances() { } bool PluginManager::RegisterPlugin( - ConstString name, const char *description, + llvm::StringRef name, llvm::StringRef description, SystemRuntimeCreateInstance create_callback) { return GetSystemRuntimeInstances().RegisterPlugin(name, description, create_callback); @@ -612,11 +617,12 @@ PluginManager::GetSystemRuntimeCreateCallbackAtIndex(uint32_t idx) { struct ObjectFileInstance : public PluginInstance<ObjectFileCreateInstance> { ObjectFileInstance( - ConstString name, std::string description, CallbackType create_callback, + llvm::StringRef name, llvm::StringRef description, + CallbackType create_callback, ObjectFileCreateMemoryInstance create_memory_callback, ObjectFileGetModuleSpecifications get_module_specifications, ObjectFileSaveCore save_core) - : PluginInstance<ObjectFileCreateInstance>(name, std::move(description), + : PluginInstance<ObjectFileCreateInstance>(name, description, create_callback), create_memory_callback(create_memory_callback), get_module_specifications(get_module_specifications), @@ -634,7 +640,7 @@ static ObjectFileInstances &GetObjectFileInstances() { } bool PluginManager::RegisterPlugin( - ConstString name, const char *description, + llvm::StringRef name, llvm::StringRef description, ObjectFileCreateInstance create_callback, ObjectFileCreateMemoryInstance create_memory_callback, ObjectFileGetModuleSpecifications get_module_specifications, @@ -672,9 +678,7 @@ PluginManager::GetObjectFileGetModuleSpecificationsCallbackAtIndex( ObjectFileCreateMemoryInstance PluginManager::GetObjectFileCreateMemoryCallbackForPluginName( - ConstString name) { - if (!name) - return nullptr; + llvm::StringRef name) { const auto &instances = GetObjectFileInstances().GetInstances(); for (auto &instance : instances) { if (instance.name == name) @@ -685,13 +689,26 @@ PluginManager::GetObjectFileCreateMemoryCallbackForPluginName( Status PluginManager::SaveCore(const lldb::ProcessSP &process_sp, const FileSpec &outfile, - lldb::SaveCoreStyle &core_style) { + lldb::SaveCoreStyle &core_style, + llvm::StringRef plugin_name) { + if (plugin_name.empty()) { + // Try saving core directly from the process plugin first. + llvm::Expected<bool> ret = process_sp->SaveCore(outfile.GetPath()); + if (!ret) + return Status(ret.takeError()); + if (ret.get()) + return Status(); + } + + // Fall back to object plugins. Status error; auto &instances = GetObjectFileInstances().GetInstances(); for (auto &instance : instances) { - if (instance.save_core && - instance.save_core(process_sp, outfile, core_style, error)) - return error; + if (plugin_name.empty() || instance.name == plugin_name) { + if (instance.save_core && + instance.save_core(process_sp, outfile, core_style, error)) + return error; + } } error.SetErrorString( "no ObjectFile plugins were able to save a core for this process"); @@ -703,10 +720,11 @@ Status PluginManager::SaveCore(const lldb::ProcessSP &process_sp, struct ObjectContainerInstance : public PluginInstance<ObjectContainerCreateInstance> { ObjectContainerInstance( - ConstString name, std::string description, CallbackType create_callback, + llvm::StringRef name, llvm::StringRef description, + CallbackType create_callback, ObjectFileGetModuleSpecifications get_module_specifications) - : PluginInstance<ObjectContainerCreateInstance>( - name, std::move(description), create_callback), + : PluginInstance<ObjectContainerCreateInstance>(name, description, + create_callback), get_module_specifications(get_module_specifications) {} ObjectFileGetModuleSpecifications get_module_specifications; @@ -719,7 +737,7 @@ static ObjectContainerInstances &GetObjectContainerInstances() { } bool PluginManager::RegisterPlugin( - ConstString name, const char *description, + llvm::StringRef name, llvm::StringRef description, ObjectContainerCreateInstance create_callback, ObjectFileGetModuleSpecifications get_module_specifications) { return GetObjectContainerInstances().RegisterPlugin( @@ -756,7 +774,7 @@ static PlatformInstances &GetPlatformInstances() { } bool PluginManager::RegisterPlugin( - ConstString name, const char *description, + llvm::StringRef name, llvm::StringRef description, PlatformCreateInstance create_callback, DebuggerInitializeCallback debugger_init_callback) { return GetPlatformInstances().RegisterPlugin( @@ -767,11 +785,12 @@ bool PluginManager::UnregisterPlugin(PlatformCreateInstance create_callback) { return GetPlatformInstances().UnregisterPlugin(create_callback); } -const char *PluginManager::GetPlatformPluginNameAtIndex(uint32_t idx) { +llvm::StringRef PluginManager::GetPlatformPluginNameAtIndex(uint32_t idx) { return GetPlatformInstances().GetNameAtIndex(idx); } -const char *PluginManager::GetPlatformPluginDescriptionAtIndex(uint32_t idx) { +llvm::StringRef +PluginManager::GetPlatformPluginDescriptionAtIndex(uint32_t idx) { return GetPlatformInstances().GetDescriptionAtIndex(idx); } @@ -781,15 +800,15 @@ PluginManager::GetPlatformCreateCallbackAtIndex(uint32_t idx) { } PlatformCreateInstance -PluginManager::GetPlatformCreateCallbackForPluginName(ConstString name) { +PluginManager::GetPlatformCreateCallbackForPluginName(llvm::StringRef name) { return GetPlatformInstances().GetCallbackForName(name); } void PluginManager::AutoCompletePlatformName(llvm::StringRef name, CompletionRequest &request) { for (const auto &instance : GetPlatformInstances().GetInstances()) { - if (instance.name.GetStringRef().startswith(name)) - request.AddCompletion(instance.name.GetCString()); + if (instance.name.startswith(name)) + request.AddCompletion(instance.name); } } @@ -804,7 +823,7 @@ static ProcessInstances &GetProcessInstances() { } bool PluginManager::RegisterPlugin( - ConstString name, const char *description, + llvm::StringRef name, llvm::StringRef description, ProcessCreateInstance create_callback, DebuggerInitializeCallback debugger_init_callback) { return GetProcessInstances().RegisterPlugin( @@ -815,11 +834,11 @@ bool PluginManager::UnregisterPlugin(ProcessCreateInstance create_callback) { return GetProcessInstances().UnregisterPlugin(create_callback); } -const char *PluginManager::GetProcessPluginNameAtIndex(uint32_t idx) { +llvm::StringRef PluginManager::GetProcessPluginNameAtIndex(uint32_t idx) { return GetProcessInstances().GetNameAtIndex(idx); } -const char *PluginManager::GetProcessPluginDescriptionAtIndex(uint32_t idx) { +llvm::StringRef PluginManager::GetProcessPluginDescriptionAtIndex(uint32_t idx) { return GetProcessInstances().GetDescriptionAtIndex(idx); } @@ -829,15 +848,15 @@ PluginManager::GetProcessCreateCallbackAtIndex(uint32_t idx) { } ProcessCreateInstance -PluginManager::GetProcessCreateCallbackForPluginName(ConstString name) { +PluginManager::GetProcessCreateCallbackForPluginName(llvm::StringRef name) { return GetProcessInstances().GetCallbackForName(name); } void PluginManager::AutoCompleteProcessName(llvm::StringRef name, CompletionRequest &request) { for (const auto &instance : GetProcessInstances().GetInstances()) { - if (instance.name.GetStringRef().startswith(name)) - request.AddCompletion(instance.name.GetCString(), instance.description); + if (instance.name.startswith(name)) + request.AddCompletion(instance.name, instance.description); } } @@ -845,11 +864,11 @@ void PluginManager::AutoCompleteProcessName(llvm::StringRef name, struct ScriptInterpreterInstance : public PluginInstance<ScriptInterpreterCreateInstance> { - ScriptInterpreterInstance(ConstString name, std::string description, + ScriptInterpreterInstance(llvm::StringRef name, llvm::StringRef description, CallbackType create_callback, lldb::ScriptLanguage language) - : PluginInstance<ScriptInterpreterCreateInstance>( - name, std::move(description), create_callback), + : PluginInstance<ScriptInterpreterCreateInstance>(name, description, + create_callback), language(language) {} lldb::ScriptLanguage language = lldb::eScriptLanguageNone; @@ -863,7 +882,7 @@ static ScriptInterpreterInstances &GetScriptInterpreterInstances() { } bool PluginManager::RegisterPlugin( - ConstString name, const char *description, + llvm::StringRef name, llvm::StringRef description, lldb::ScriptLanguage script_language, ScriptInterpreterCreateInstance create_callback) { return GetScriptInterpreterInstances().RegisterPlugin( @@ -903,12 +922,12 @@ PluginManager::GetScriptInterpreterForLanguage(lldb::ScriptLanguage script_lang, struct StructuredDataPluginInstance : public PluginInstance<StructuredDataPluginCreateInstance> { StructuredDataPluginInstance( - ConstString name, std::string description, CallbackType create_callback, + llvm::StringRef name, llvm::StringRef description, + CallbackType create_callback, DebuggerInitializeCallback debugger_init_callback, StructuredDataFilterLaunchInfo filter_callback) : PluginInstance<StructuredDataPluginCreateInstance>( - name, std::move(description), create_callback, - debugger_init_callback), + name, description, create_callback, debugger_init_callback), filter_callback(filter_callback) {} StructuredDataFilterLaunchInfo filter_callback = nullptr; @@ -923,7 +942,7 @@ static StructuredDataPluginInstances &GetStructuredDataPluginInstances() { } bool PluginManager::RegisterPlugin( - ConstString name, const char *description, + llvm::StringRef name, llvm::StringRef description, StructuredDataPluginCreateInstance create_callback, DebuggerInitializeCallback debugger_init_callback, StructuredDataFilterLaunchInfo filter_callback) { @@ -966,7 +985,7 @@ static SymbolFileInstances &GetSymbolFileInstances() { } bool PluginManager::RegisterPlugin( - ConstString name, const char *description, + llvm::StringRef name, llvm::StringRef description, SymbolFileCreateInstance create_callback, DebuggerInitializeCallback debugger_init_callback) { return GetSymbolFileInstances().RegisterPlugin( @@ -992,7 +1011,8 @@ static SymbolVendorInstances &GetSymbolVendorInstances() { return g_instances; } -bool PluginManager::RegisterPlugin(ConstString name, const char *description, +bool PluginManager::RegisterPlugin(llvm::StringRef name, + llvm::StringRef description, SymbolVendorCreateInstance create_callback) { return GetSymbolVendorInstances().RegisterPlugin(name, description, create_callback); @@ -1013,12 +1033,12 @@ PluginManager::GetSymbolVendorCreateCallbackAtIndex(uint32_t idx) { struct TraceInstance : public PluginInstance<TraceCreateInstanceForSessionFile> { TraceInstance( - ConstString name, std::string description, + llvm::StringRef name, llvm::StringRef description, CallbackType create_callback_for_session_file, TraceCreateInstanceForLiveProcess create_callback_for_live_process, llvm::StringRef schema) : PluginInstance<TraceCreateInstanceForSessionFile>( - name, std::move(description), create_callback_for_session_file), + name, description, create_callback_for_session_file), schema(schema), create_callback_for_live_process(create_callback_for_live_process) {} @@ -1034,7 +1054,7 @@ static TraceInstances &GetTracePluginInstances() { } bool PluginManager::RegisterPlugin( - ConstString name, const char *description, + llvm::StringRef name, llvm::StringRef description, TraceCreateInstanceForSessionFile create_callback_for_session_file, TraceCreateInstanceForLiveProcess create_callback_for_live_process, llvm::StringRef schema) { @@ -1050,19 +1070,19 @@ bool PluginManager::UnregisterPlugin( } TraceCreateInstanceForSessionFile -PluginManager::GetTraceCreateCallback(ConstString plugin_name) { +PluginManager::GetTraceCreateCallback(llvm::StringRef plugin_name) { return GetTracePluginInstances().GetCallbackForName(plugin_name); } TraceCreateInstanceForLiveProcess -PluginManager::GetTraceCreateCallbackForLiveProcess(ConstString plugin_name) { +PluginManager::GetTraceCreateCallbackForLiveProcess(llvm::StringRef plugin_name) { for (const TraceInstance &instance : GetTracePluginInstances().GetInstances()) if (instance.name == plugin_name) return instance.create_callback_for_live_process; return nullptr; } -llvm::StringRef PluginManager::GetTraceSchema(ConstString plugin_name) { +llvm::StringRef PluginManager::GetTraceSchema(llvm::StringRef plugin_name) { for (const TraceInstance &instance : GetTracePluginInstances().GetInstances()) if (instance.name == plugin_name) return instance.schema; @@ -1081,11 +1101,11 @@ llvm::StringRef PluginManager::GetTraceSchema(size_t index) { struct TraceExporterInstance : public PluginInstance<TraceExporterCreateInstance> { TraceExporterInstance( - ConstString name, std::string description, + llvm::StringRef name, llvm::StringRef description, TraceExporterCreateInstance create_instance, ThreadTraceExportCommandCreator create_thread_trace_export_command) - : PluginInstance<TraceExporterCreateInstance>( - name, std::move(description), create_instance), + : PluginInstance<TraceExporterCreateInstance>(name, description, + create_instance), create_thread_trace_export_command(create_thread_trace_export_command) { } @@ -1100,7 +1120,7 @@ static TraceExporterInstances &GetTraceExporterInstances() { } bool PluginManager::RegisterPlugin( - ConstString name, const char *description, + llvm::StringRef name, llvm::StringRef description, TraceExporterCreateInstance create_callback, ThreadTraceExportCommandCreator create_thread_trace_export_command) { return GetTraceExporterInstances().RegisterPlugin( @@ -1108,7 +1128,7 @@ bool PluginManager::RegisterPlugin( } TraceExporterCreateInstance -PluginManager::GetTraceExporterCreateCallback(ConstString plugin_name) { +PluginManager::GetTraceExporterCreateCallback(llvm::StringRef plugin_name) { return GetTraceExporterInstances().GetCallbackForName(plugin_name); } @@ -1125,7 +1145,8 @@ PluginManager::GetThreadTraceExportCommandCreatorAtIndex(uint32_t index) { return nullptr; } -const char *PluginManager::GetTraceExporterPluginNameAtIndex(uint32_t index) { +llvm::StringRef +PluginManager::GetTraceExporterPluginNameAtIndex(uint32_t index) { return GetTraceExporterInstances().GetNameAtIndex(index); } @@ -1140,7 +1161,7 @@ static UnwindAssemblyInstances &GetUnwindAssemblyInstances() { } bool PluginManager::RegisterPlugin( - ConstString name, const char *description, + llvm::StringRef name, llvm::StringRef description, UnwindAssemblyCreateInstance create_callback) { return GetUnwindAssemblyInstances().RegisterPlugin(name, description, create_callback); @@ -1167,7 +1188,7 @@ static MemoryHistoryInstances &GetMemoryHistoryInstances() { } bool PluginManager::RegisterPlugin( - ConstString name, const char *description, + llvm::StringRef name, llvm::StringRef description, MemoryHistoryCreateInstance create_callback) { return GetMemoryHistoryInstances().RegisterPlugin(name, description, create_callback); @@ -1188,10 +1209,11 @@ PluginManager::GetMemoryHistoryCreateCallbackAtIndex(uint32_t idx) { struct InstrumentationRuntimeInstance : public PluginInstance<InstrumentationRuntimeCreateInstance> { InstrumentationRuntimeInstance( - ConstString name, std::string description, CallbackType create_callback, + llvm::StringRef name, llvm::StringRef description, + CallbackType create_callback, InstrumentationRuntimeGetType get_type_callback) - : PluginInstance<InstrumentationRuntimeCreateInstance>( - name, std::move(description), create_callback), + : PluginInstance<InstrumentationRuntimeCreateInstance>(name, description, + create_callback), get_type_callback(get_type_callback) {} InstrumentationRuntimeGetType get_type_callback = nullptr; @@ -1206,7 +1228,7 @@ static InstrumentationRuntimeInstances &GetInstrumentationRuntimeInstances() { } bool PluginManager::RegisterPlugin( - ConstString name, const char *description, + llvm::StringRef name, llvm::StringRef description, InstrumentationRuntimeCreateInstance create_callback, InstrumentationRuntimeGetType get_type_callback) { return GetInstrumentationRuntimeInstances().RegisterPlugin( @@ -1234,11 +1256,11 @@ PluginManager::GetInstrumentationRuntimeCreateCallbackAtIndex(uint32_t idx) { #pragma mark TypeSystem struct TypeSystemInstance : public PluginInstance<TypeSystemCreateInstance> { - TypeSystemInstance(ConstString name, std::string description, + TypeSystemInstance(llvm::StringRef name, llvm::StringRef description, CallbackType create_callback, LanguageSet supported_languages_for_types, LanguageSet supported_languages_for_expressions) - : PluginInstance<TypeSystemCreateInstance>(name, std::move(description), + : PluginInstance<TypeSystemCreateInstance>(name, description, create_callback), supported_languages_for_types(supported_languages_for_types), supported_languages_for_expressions( @@ -1256,7 +1278,7 @@ static TypeSystemInstances &GetTypeSystemInstances() { } bool PluginManager::RegisterPlugin( - ConstString name, const char *description, + llvm::StringRef name, llvm::StringRef description, TypeSystemCreateInstance create_callback, LanguageSet supported_languages_for_types, LanguageSet supported_languages_for_expressions) { @@ -1293,10 +1315,9 @@ LanguageSet PluginManager::GetAllTypeSystemSupportedLanguagesForExpressions() { #pragma mark REPL struct REPLInstance : public PluginInstance<REPLCreateInstance> { - REPLInstance(ConstString name, std::string description, + REPLInstance(llvm::StringRef name, llvm::StringRef description, CallbackType create_callback, LanguageSet supported_languages) - : PluginInstance<REPLCreateInstance>(name, std::move(description), - create_callback), + : PluginInstance<REPLCreateInstance>(name, description, create_callback), supported_languages(supported_languages) {} LanguageSet supported_languages; @@ -1309,7 +1330,7 @@ static REPLInstances &GetREPLInstances() { return g_instances; } -bool PluginManager::RegisterPlugin(ConstString name, const char *description, +bool PluginManager::RegisterPlugin(llvm::StringRef name, llvm::StringRef description, REPLCreateInstance create_callback, LanguageSet supported_languages) { return GetREPLInstances().RegisterPlugin(name, description, create_callback, @@ -1421,8 +1442,9 @@ namespace { typedef lldb::OptionValuePropertiesSP GetDebuggerPropertyForPluginsPtr(Debugger &, ConstString, ConstString, bool can_create); +} -lldb::OptionValuePropertiesSP +static lldb::OptionValuePropertiesSP GetSettingForPlugin(Debugger &debugger, ConstString setting_name, ConstString plugin_type_name, GetDebuggerPropertyForPluginsPtr get_debugger_property = @@ -1438,13 +1460,13 @@ GetSettingForPlugin(Debugger &debugger, ConstString setting_name, return properties_sp; } -bool CreateSettingForPlugin( - Debugger &debugger, ConstString plugin_type_name, - ConstString plugin_type_desc, - const lldb::OptionValuePropertiesSP &properties_sp, ConstString description, - bool is_global_property, - GetDebuggerPropertyForPluginsPtr get_debugger_property = - GetDebuggerPropertyForPlugins) { +static bool +CreateSettingForPlugin(Debugger &debugger, ConstString plugin_type_name, + ConstString plugin_type_desc, + const lldb::OptionValuePropertiesSP &properties_sp, + ConstString description, bool is_global_property, + GetDebuggerPropertyForPluginsPtr get_debugger_property = + GetDebuggerPropertyForPlugins) { if (properties_sp) { lldb::OptionValuePropertiesSP plugin_type_properties_sp( get_debugger_property(debugger, plugin_type_name, plugin_type_desc, @@ -1459,14 +1481,12 @@ bool CreateSettingForPlugin( return false; } -const char *kDynamicLoaderPluginName("dynamic-loader"); -const char *kPlatformPluginName("platform"); -const char *kProcessPluginName("process"); -const char *kSymbolFilePluginName("symbol-file"); -const char *kJITLoaderPluginName("jit-loader"); -const char *kStructuredDataPluginName("structured-data"); - -} // anonymous namespace +static const char *kDynamicLoaderPluginName("dynamic-loader"); +static const char *kPlatformPluginName("platform"); +static const char *kProcessPluginName("process"); +static const char *kSymbolFilePluginName("symbol-file"); +static const char *kJITLoaderPluginName("jit-loader"); +static const char *kStructuredDataPluginName("structured-data"); lldb::OptionValuePropertiesSP PluginManager::GetSettingForDynamicLoaderPlugin(Debugger &debugger, diff --git a/contrib/llvm-project/lldb/source/Core/RichManglingContext.cpp b/contrib/llvm-project/lldb/source/Core/RichManglingContext.cpp index 2dcb1407e6c7..63170feb6231 100644 --- a/contrib/llvm-project/lldb/source/Core/RichManglingContext.cpp +++ b/contrib/llvm-project/lldb/source/Core/RichManglingContext.cpp @@ -83,19 +83,6 @@ bool RichManglingContext::IsCtorOrDtor() const { llvm_unreachable("Fully covered switch above!"); } -bool RichManglingContext::IsFunction() const { - assert(m_provider != None && "Initialize a provider first"); - switch (m_provider) { - case ItaniumPartialDemangler: - return m_ipd.isFunction(); - case PluginCxxLanguage: - return get<CPlusPlusLanguage::MethodName>(m_cxx_method_parser)->IsValid(); - case None: - return false; - } - llvm_unreachable("Fully covered switch above!"); -} - void RichManglingContext::processIPDStrResult(char *ipd_res, size_t res_size) { // Error case: Clear the buffer. if (LLVM_UNLIKELY(ipd_res == nullptr)) { diff --git a/contrib/llvm-project/lldb/source/Core/Section.cpp b/contrib/llvm-project/lldb/source/Core/Section.cpp index a5a10141aa64..1660e3c92f2c 100644 --- a/contrib/llvm-project/lldb/source/Core/Section.cpp +++ b/contrib/llvm-project/lldb/source/Core/Section.cpp @@ -396,6 +396,76 @@ lldb::offset_t Section::GetSectionData(DataExtractor §ion_data) { return 0; } +bool Section::ContainsOnlyDebugInfo() const { + switch (m_type) { + case eSectionTypeInvalid: + case eSectionTypeCode: + case eSectionTypeContainer: + case eSectionTypeData: + case eSectionTypeDataCString: + case eSectionTypeDataCStringPointers: + case eSectionTypeDataSymbolAddress: + case eSectionTypeData4: + case eSectionTypeData8: + case eSectionTypeData16: + case eSectionTypeDataPointers: + case eSectionTypeZeroFill: + case eSectionTypeDataObjCMessageRefs: + case eSectionTypeDataObjCCFStrings: + case eSectionTypeELFSymbolTable: + case eSectionTypeELFDynamicSymbols: + case eSectionTypeELFRelocationEntries: + case eSectionTypeELFDynamicLinkInfo: + case eSectionTypeEHFrame: + case eSectionTypeARMexidx: + case eSectionTypeARMextab: + case eSectionTypeCompactUnwind: + case eSectionTypeGoSymtab: + case eSectionTypeAbsoluteAddress: + case eSectionTypeOther: + return false; + + case eSectionTypeDebug: + case eSectionTypeDWARFDebugAbbrev: + case eSectionTypeDWARFDebugAbbrevDwo: + case eSectionTypeDWARFDebugAddr: + case eSectionTypeDWARFDebugAranges: + case eSectionTypeDWARFDebugCuIndex: + case eSectionTypeDWARFDebugTuIndex: + case eSectionTypeDWARFDebugFrame: + case eSectionTypeDWARFDebugInfo: + case eSectionTypeDWARFDebugInfoDwo: + case eSectionTypeDWARFDebugLine: + case eSectionTypeDWARFDebugLineStr: + case eSectionTypeDWARFDebugLoc: + case eSectionTypeDWARFDebugLocDwo: + case eSectionTypeDWARFDebugLocLists: + case eSectionTypeDWARFDebugLocListsDwo: + case eSectionTypeDWARFDebugMacInfo: + case eSectionTypeDWARFDebugMacro: + case eSectionTypeDWARFDebugPubNames: + case eSectionTypeDWARFDebugPubTypes: + case eSectionTypeDWARFDebugRanges: + case eSectionTypeDWARFDebugRngLists: + case eSectionTypeDWARFDebugRngListsDwo: + case eSectionTypeDWARFDebugStr: + case eSectionTypeDWARFDebugStrDwo: + case eSectionTypeDWARFDebugStrOffsets: + case eSectionTypeDWARFDebugStrOffsetsDwo: + case eSectionTypeDWARFDebugTypes: + case eSectionTypeDWARFDebugTypesDwo: + case eSectionTypeDWARFDebugNames: + case eSectionTypeDWARFAppleNames: + case eSectionTypeDWARFAppleTypes: + case eSectionTypeDWARFAppleNamespaces: + case eSectionTypeDWARFAppleObjC: + case eSectionTypeDWARFGNUDebugAltLink: + return true; + } + return false; +} + + #pragma mark SectionList SectionList &SectionList::operator=(const SectionList &rhs) { @@ -599,3 +669,15 @@ size_t SectionList::Slide(addr_t slide_amount, bool slide_children) { } return count; } + +uint64_t SectionList::GetDebugInfoSize() const { + uint64_t debug_info_size = 0; + for (const auto §ion : m_sections) { + const SectionList &sub_sections = section->GetChildren(); + if (sub_sections.GetSize() > 0) + debug_info_size += sub_sections.GetDebugInfoSize(); + else if (section->ContainsOnlyDebugInfo()) + debug_info_size += section->GetFileSize(); + } + return debug_info_size; +} diff --git a/contrib/llvm-project/lldb/source/Core/SourceManager.cpp b/contrib/llvm-project/lldb/source/Core/SourceManager.cpp index 9c1112979c54..effba485f026 100644 --- a/contrib/llvm-project/lldb/source/Core/SourceManager.cpp +++ b/contrib/llvm-project/lldb/source/Core/SourceManager.cpp @@ -339,11 +339,14 @@ bool SourceManager::GetDefaultFileAndLine(FileSpec &file_spec, uint32_t &line) { if (executable_ptr) { SymbolContextList sc_list; ConstString main_name("main"); - bool symbols_okay = false; // Force it to be a debug symbol. - bool inlines_okay = true; + + ModuleFunctionSearchOptions function_options; + function_options.include_symbols = + false; // Force it to be a debug symbol. + function_options.include_inlines = true; executable_ptr->FindFunctions(main_name, CompilerDeclContext(), - lldb::eFunctionNameTypeBase, inlines_okay, - symbols_okay, sc_list); + lldb::eFunctionNameTypeBase, + function_options, sc_list); size_t num_matches = sc_list.GetSize(); for (size_t idx = 0; idx < num_matches; idx++) { SymbolContext sc; diff --git a/contrib/llvm-project/lldb/source/Core/StreamFile.cpp b/contrib/llvm-project/lldb/source/Core/StreamFile.cpp index 2f922fe11440..7753397ae0f1 100644 --- a/contrib/llvm-project/lldb/source/Core/StreamFile.cpp +++ b/contrib/llvm-project/lldb/source/Core/StreamFile.cpp @@ -21,8 +21,8 @@ StreamFile::StreamFile(uint32_t flags, uint32_t addr_size, ByteOrder byte_order) } StreamFile::StreamFile(int fd, bool transfer_ownership) : Stream() { - m_file_sp = - std::make_shared<NativeFile>(fd, File::eOpenOptionWrite, transfer_ownership); + m_file_sp = std::make_shared<NativeFile>(fd, File::eOpenOptionWriteOnly, + transfer_ownership); } StreamFile::StreamFile(FILE *fh, bool transfer_ownership) : Stream() { diff --git a/contrib/llvm-project/lldb/source/Core/ValueObject.cpp b/contrib/llvm-project/lldb/source/Core/ValueObject.cpp index 9c1ba99da1d0..6794d0c7331d 100644 --- a/contrib/llvm-project/lldb/source/Core/ValueObject.cpp +++ b/contrib/llvm-project/lldb/source/Core/ValueObject.cpp @@ -849,8 +849,10 @@ bool ValueObject::SetData(DataExtractor &data, Status &error) { static bool CopyStringDataToBufferSP(const StreamString &source, lldb::DataBufferSP &destination) { - destination = std::make_shared<DataBufferHeap>(source.GetSize() + 1, 0); - memcpy(destination->GetBytes(), source.GetString().data(), source.GetSize()); + llvm::StringRef src = source.GetString(); + src.consume_back(llvm::StringRef("\0", 1)); + destination = std::make_shared<DataBufferHeap>(src.size(), 0); + memcpy(destination->GetBytes(), src.data(), src.size()); return true; } @@ -912,8 +914,8 @@ ValueObject::ReadPointedString(lldb::DataBufferSP &buffer_sp, Status &error, CopyStringDataToBufferSP(s, buffer_sp); return {0, was_capped}; } - buffer_sp = std::make_shared<DataBufferHeap>(cstr_len, 0); - memcpy(buffer_sp->GetBytes(), cstr, cstr_len); + s << llvm::StringRef(cstr, cstr_len); + CopyStringDataToBufferSP(s, buffer_sp); return {cstr_len, was_capped}; } else { s << "<invalid address>"; @@ -1196,6 +1198,7 @@ bool ValueObject::DumpPrintableRepresentation( options.SetQuote('"'); options.SetSourceSize(buffer_sp->GetByteSize()); options.SetIsTruncated(read_string.second); + options.SetBinaryZeroIsTerminator(custom_format != eFormatVectorOfChar); formatters::StringPrinter::ReadBufferAndDumpToStream< lldb_private::formatters::StringPrinter::StringElementType::ASCII>( options); diff --git a/contrib/llvm-project/lldb/source/Core/ValueObjectConstResultImpl.cpp b/contrib/llvm-project/lldb/source/Core/ValueObjectConstResultImpl.cpp index 980cea049f6f..fee1da138bbc 100644 --- a/contrib/llvm-project/lldb/source/Core/ValueObjectConstResultImpl.cpp +++ b/contrib/llvm-project/lldb/source/Core/ValueObjectConstResultImpl.cpp @@ -34,7 +34,7 @@ using namespace lldb_private; ValueObjectConstResultImpl::ValueObjectConstResultImpl( ValueObject *valobj, lldb::addr_t live_address) : m_impl_backend(valobj), m_live_address(live_address), - m_live_address_type(eAddressTypeLoad), m_load_addr_backend(), + m_live_address_type(eAddressTypeLoad), m_address_of_backend() {} lldb::ValueObjectSP ValueObjectConstResultImpl::Dereference(Status &error) { diff --git a/contrib/llvm-project/lldb/source/Core/ValueObjectDynamicValue.cpp b/contrib/llvm-project/lldb/source/Core/ValueObjectDynamicValue.cpp index d77509496509..bf087f33c0e9 100644 --- a/contrib/llvm-project/lldb/source/Core/ValueObjectDynamicValue.cpp +++ b/contrib/llvm-project/lldb/source/Core/ValueObjectDynamicValue.cpp @@ -36,10 +36,6 @@ ValueObjectDynamicValue::ValueObjectDynamicValue( SetName(parent.GetName()); } -ValueObjectDynamicValue::~ValueObjectDynamicValue() { - m_owning_valobj_sp.reset(); -} - CompilerType ValueObjectDynamicValue::GetCompilerTypeImpl() { const bool success = UpdateValueIfNeeded(false); if (success) { diff --git a/contrib/llvm-project/lldb/source/Core/ValueObjectRegister.cpp b/contrib/llvm-project/lldb/source/Core/ValueObjectRegister.cpp index 089fd7667080..743083a2d1ed 100644 --- a/contrib/llvm-project/lldb/source/Core/ValueObjectRegister.cpp +++ b/contrib/llvm-project/lldb/source/Core/ValueObjectRegister.cpp @@ -118,8 +118,9 @@ ValueObject *ValueObjectRegisterSet::CreateChildAtIndex( if (m_reg_ctx_sp && m_reg_set) { const size_t num_children = GetNumChildren(); if (idx < num_children) - valobj = new ValueObjectRegister(*this, m_reg_ctx_sp, - m_reg_set->registers[idx]); + valobj = new ValueObjectRegister( + *this, m_reg_ctx_sp, + m_reg_ctx_sp->GetRegisterInfoAtIndex(m_reg_set->registers[idx])); } return valobj; } @@ -132,8 +133,7 @@ ValueObjectRegisterSet::GetChildMemberWithName(ConstString name, const RegisterInfo *reg_info = m_reg_ctx_sp->GetRegisterInfoByName(name.GetStringRef()); if (reg_info != nullptr) - valobj = new ValueObjectRegister(*this, m_reg_ctx_sp, - reg_info->kinds[eRegisterKindLLDB]); + valobj = new ValueObjectRegister(*this, m_reg_ctx_sp, reg_info); } if (valobj) return valobj->GetSP(); @@ -155,8 +155,7 @@ ValueObjectRegisterSet::GetIndexOfChildWithName(ConstString name) { #pragma mark - #pragma mark ValueObjectRegister -void ValueObjectRegister::ConstructObject(uint32_t reg_num) { - const RegisterInfo *reg_info = m_reg_ctx_sp->GetRegisterInfoAtIndex(reg_num); +void ValueObjectRegister::ConstructObject(const RegisterInfo *reg_info) { if (reg_info) { m_reg_info = *reg_info; if (reg_info->name) @@ -168,29 +167,29 @@ void ValueObjectRegister::ConstructObject(uint32_t reg_num) { ValueObjectRegister::ValueObjectRegister(ValueObject &parent, lldb::RegisterContextSP ®_ctx_sp, - uint32_t reg_num) + const RegisterInfo *reg_info) : ValueObject(parent), m_reg_ctx_sp(reg_ctx_sp), m_reg_info(), m_reg_value(), m_type_name(), m_compiler_type() { assert(reg_ctx_sp.get()); - ConstructObject(reg_num); + ConstructObject(reg_info); } ValueObjectSP ValueObjectRegister::Create(ExecutionContextScope *exe_scope, lldb::RegisterContextSP ®_ctx_sp, - uint32_t reg_num) { + const RegisterInfo *reg_info) { auto manager_sp = ValueObjectManager::Create(); - return (new ValueObjectRegister(exe_scope, *manager_sp, reg_ctx_sp, reg_num)) + return (new ValueObjectRegister(exe_scope, *manager_sp, reg_ctx_sp, reg_info)) ->GetSP(); } ValueObjectRegister::ValueObjectRegister(ExecutionContextScope *exe_scope, ValueObjectManager &manager, lldb::RegisterContextSP ®_ctx, - uint32_t reg_num) + const RegisterInfo *reg_info) : ValueObject(exe_scope, manager), m_reg_ctx_sp(reg_ctx), m_reg_info(), m_reg_value(), m_type_name(), m_compiler_type() { assert(reg_ctx); - ConstructObject(reg_num); + ConstructObject(reg_info); } ValueObjectRegister::~ValueObjectRegister() = default; diff --git a/contrib/llvm-project/lldb/source/DataFormatters/FormatManager.cpp b/contrib/llvm-project/lldb/source/DataFormatters/FormatManager.cpp index 6c824d1f7728..cda1ae60d857 100644 --- a/contrib/llvm-project/lldb/source/DataFormatters/FormatManager.cpp +++ b/contrib/llvm-project/lldb/source/DataFormatters/FormatManager.cpp @@ -722,9 +722,9 @@ void FormatManager::LoadSystemFormatters() { new StringSummaryFormat(string_flags, "${var%s}")); lldb::TypeSummaryImplSP string_array_format( - new StringSummaryFormat(string_array_flags, "${var%s}")); + new StringSummaryFormat(string_array_flags, "${var%char[]}")); - RegularExpression any_size_char_arr(llvm::StringRef("char \\[[0-9]+\\]")); + RegularExpression any_size_char_arr(llvm::StringRef("char ?\\[[0-9]+\\]")); TypeCategoryImpl::SharedPointer sys_category_sp = GetCategory(m_system_category_name); @@ -773,12 +773,11 @@ void FormatManager::LoadVectorFormatters() { AddStringSummary(vectors_category_sp, "${var.uint128}", ConstString("builtin_type_vec128"), vector_flags); - - AddStringSummary(vectors_category_sp, "", ConstString("float [4]"), + AddStringSummary(vectors_category_sp, "", ConstString("float[4]"), vector_flags); - AddStringSummary(vectors_category_sp, "", ConstString("int32_t [4]"), + AddStringSummary(vectors_category_sp, "", ConstString("int32_t[4]"), vector_flags); - AddStringSummary(vectors_category_sp, "", ConstString("int16_t [8]"), + AddStringSummary(vectors_category_sp, "", ConstString("int16_t[8]"), vector_flags); AddStringSummary(vectors_category_sp, "", ConstString("vDouble"), vector_flags); diff --git a/contrib/llvm-project/lldb/source/DataFormatters/FormattersHelpers.cpp b/contrib/llvm-project/lldb/source/DataFormatters/FormattersHelpers.cpp index 7944ff06eee5..b9c6b017e293 100644 --- a/contrib/llvm-project/lldb/source/DataFormatters/FormattersHelpers.cpp +++ b/contrib/llvm-project/lldb/source/DataFormatters/FormattersHelpers.cpp @@ -10,7 +10,7 @@ #include "lldb/DataFormatters/FormattersHelpers.h" - +#include "lldb/Core/Module.h" #include "lldb/Target/StackFrame.h" #include "lldb/Target/Target.h" #include "lldb/Target/Thread.h" @@ -131,14 +131,17 @@ size_t lldb_private::formatters::ExtractIndexFromString(const char *item_name) { return idx; } -lldb::addr_t +Address lldb_private::formatters::GetArrayAddressOrPointerValue(ValueObject &valobj) { lldb::addr_t data_addr = LLDB_INVALID_ADDRESS; + AddressType type; if (valobj.IsPointerType()) - data_addr = valobj.GetValueAsUnsigned(0); + data_addr = valobj.GetPointerValue(&type); else if (valobj.IsArrayType()) - data_addr = valobj.GetAddressOf(); + data_addr = valobj.GetAddressOf(/*scalar_is_load_address=*/true, &type); + if (data_addr != LLDB_INVALID_ADDRESS && type == eAddressTypeFile) + return Address(data_addr, valobj.GetModule()->GetSectionList()); return data_addr; } diff --git a/contrib/llvm-project/lldb/source/DataFormatters/StringPrinter.cpp b/contrib/llvm-project/lldb/source/DataFormatters/StringPrinter.cpp index 0c6438f7dd86..ec8664ebe17a 100644 --- a/contrib/llvm-project/lldb/source/DataFormatters/StringPrinter.cpp +++ b/contrib/llvm-project/lldb/source/DataFormatters/StringPrinter.cpp @@ -408,8 +408,8 @@ static bool ReadEncodedBufferAndDumpToStream( options.GetLocation() == LLDB_INVALID_ADDRESS) return false; - lldb::ProcessSP process_sp(options.GetProcessSP()); - if (!process_sp) + lldb::TargetSP target_sp = options.GetTargetSP(); + if (!target_sp) return false; constexpr int type_width = sizeof(SourceDataType); @@ -423,7 +423,7 @@ static bool ReadEncodedBufferAndDumpToStream( bool needs_zero_terminator = options.GetNeedsZeroTermination(); bool is_truncated = false; - const auto max_size = process_sp->GetTarget().GetMaximumSizeOfStringSummary(); + const auto max_size = target_sp->GetMaximumSizeOfStringSummary(); uint32_t sourceSize; if (elem_type == StringElementType::ASCII && !options.GetSourceSize()) { @@ -462,24 +462,22 @@ static bool ReadEncodedBufferAndDumpToStream( char *buffer = reinterpret_cast<char *>(buffer_sp->GetBytes()); if (elem_type == StringElementType::ASCII) - process_sp->ReadCStringFromMemory(options.GetLocation(), buffer, + target_sp->ReadCStringFromMemory(options.GetLocation(), buffer, bufferSPSize, error); else if (needs_zero_terminator) - process_sp->ReadStringFromMemory(options.GetLocation(), buffer, + target_sp->ReadStringFromMemory(options.GetLocation(), buffer, bufferSPSize, error, type_width); else - process_sp->ReadMemoryFromInferior(options.GetLocation(), buffer, - bufferSPSize, error); + target_sp->ReadMemory(options.GetLocation(), buffer, bufferSPSize, error); if (error.Fail()) { options.GetStream()->Printf("unable to read data"); return true; } - DataExtractor data(buffer_sp, process_sp->GetByteOrder(), - process_sp->GetAddressByteSize()); - StringPrinter::ReadBufferAndDumpToStreamOptions dump_options(options); - dump_options.SetData(data); + dump_options.SetData( + DataExtractor(buffer_sp, target_sp->GetArchitecture().GetByteOrder(), + target_sp->GetArchitecture().GetAddressByteSize())); dump_options.SetSourceSize(sourceSize); dump_options.SetIsTruncated(is_truncated); dump_options.SetNeedsZeroTermination(needs_zero_terminator); diff --git a/contrib/llvm-project/lldb/source/Expression/FunctionCaller.cpp b/contrib/llvm-project/lldb/source/Expression/FunctionCaller.cpp index 5f1eb24a905a..5f34675b4b64 100644 --- a/contrib/llvm-project/lldb/source/Expression/FunctionCaller.cpp +++ b/contrib/llvm-project/lldb/source/Expression/FunctionCaller.cpp @@ -254,7 +254,7 @@ lldb::ThreadPlanSP FunctionCaller::GetThreadPlanToCallFunction( lldb::ThreadPlanSP new_plan_sp(new ThreadPlanCallFunction( *thread, wrapper_address, CompilerType(), args, options)); - new_plan_sp->SetIsMasterPlan(true); + new_plan_sp->SetIsControllingPlan(true); new_plan_sp->SetOkayToDiscard(false); return new_plan_sp; } diff --git a/contrib/llvm-project/lldb/source/Expression/IRExecutionUnit.cpp b/contrib/llvm-project/lldb/source/Expression/IRExecutionUnit.cpp index 63184ba477a6..f2d22f7ed9cc 100644 --- a/contrib/llvm-project/lldb/source/Expression/IRExecutionUnit.cpp +++ b/contrib/llvm-project/lldb/source/Expression/IRExecutionUnit.cpp @@ -26,6 +26,7 @@ #include "lldb/Symbol/SymbolFile.h" #include "lldb/Symbol/SymbolVendor.h" #include "lldb/Target/ExecutionContext.h" +#include "lldb/Target/Language.h" #include "lldb/Target/LanguageRuntime.h" #include "lldb/Target/Target.h" #include "lldb/Utility/DataBufferHeap.h" @@ -33,7 +34,6 @@ #include "lldb/Utility/LLDBAssert.h" #include "lldb/Utility/Log.h" -#include "lldb/../../source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.h" #include "lldb/../../source/Plugins/ObjectFile/JIT/ObjectFileJIT.h" using namespace lldb_private; @@ -652,257 +652,168 @@ uint8_t *IRExecutionUnit::MemoryManager::allocateDataSection( return return_value; } -static ConstString FindBestAlternateMangledName(ConstString demangled, - const SymbolContext &sym_ctx) { - CPlusPlusLanguage::MethodName cpp_name(demangled); - std::string scope_qualified_name = cpp_name.GetScopeQualifiedName(); - - if (!scope_qualified_name.size()) - return ConstString(); - - if (!sym_ctx.module_sp) - return ConstString(); - - lldb_private::SymbolFile *sym_file = sym_ctx.module_sp->GetSymbolFile(); - if (!sym_file) - return ConstString(); - - std::vector<ConstString> alternates; - sym_file->GetMangledNamesForFunction(scope_qualified_name, alternates); +void IRExecutionUnit::CollectCandidateCNames(std::vector<ConstString> &C_names, + ConstString name) { + if (m_strip_underscore && name.AsCString()[0] == '_') + C_names.insert(C_names.begin(), ConstString(&name.AsCString()[1])); + C_names.push_back(name); +} - std::vector<ConstString> param_and_qual_matches; - std::vector<ConstString> param_matches; - for (size_t i = 0; i < alternates.size(); i++) { - ConstString alternate_mangled_name = alternates[i]; - Mangled mangled(alternate_mangled_name); - ConstString demangled = mangled.GetDemangledName(); +void IRExecutionUnit::CollectCandidateCPlusPlusNames( + std::vector<ConstString> &CPP_names, + const std::vector<ConstString> &C_names, const SymbolContext &sc) { + if (auto *cpp_lang = Language::FindPlugin(lldb::eLanguageTypeC_plus_plus)) { + for (const ConstString &name : C_names) { + Mangled mangled(name); + if (cpp_lang->SymbolNameFitsToLanguage(mangled)) { + if (ConstString best_alternate = + cpp_lang->FindBestAlternateFunctionMangledName(mangled, sc)) { + CPP_names.push_back(best_alternate); + } + } - CPlusPlusLanguage::MethodName alternate_cpp_name(demangled); - if (!cpp_name.IsValid()) - continue; + std::vector<ConstString> alternates = + cpp_lang->GenerateAlternateFunctionManglings(name); + CPP_names.insert(CPP_names.end(), alternates.begin(), alternates.end()); - if (alternate_cpp_name.GetArguments() == cpp_name.GetArguments()) { - if (alternate_cpp_name.GetQualifiers() == cpp_name.GetQualifiers()) - param_and_qual_matches.push_back(alternate_mangled_name); - else - param_matches.push_back(alternate_mangled_name); + // As a last-ditch fallback, try the base name for C++ names. It's + // terrible, but the DWARF doesn't always encode "extern C" correctly. + ConstString basename = + cpp_lang->GetDemangledFunctionNameWithoutArguments(mangled); + CPP_names.push_back(basename); } } - - if (param_and_qual_matches.size()) - return param_and_qual_matches[0]; // It is assumed that there will be only - // one! - else if (param_matches.size()) - return param_matches[0]; // Return one of them as a best match - else - return ConstString(); } -struct IRExecutionUnit::SearchSpec { - ConstString name; - lldb::FunctionNameType mask; - - SearchSpec(ConstString n, - lldb::FunctionNameType m = lldb::eFunctionNameTypeFull) - : name(n), mask(m) {} -}; +class LoadAddressResolver { +public: + LoadAddressResolver(Target *target, bool &symbol_was_missing_weak) + : m_target(target), m_symbol_was_missing_weak(symbol_was_missing_weak) {} -void IRExecutionUnit::CollectCandidateCNames( - std::vector<IRExecutionUnit::SearchSpec> &C_specs, - ConstString name) { - if (m_strip_underscore && name.AsCString()[0] == '_') - C_specs.insert(C_specs.begin(), ConstString(&name.AsCString()[1])); - C_specs.push_back(SearchSpec(name)); -} - -void IRExecutionUnit::CollectCandidateCPlusPlusNames( - std::vector<IRExecutionUnit::SearchSpec> &CPP_specs, - const std::vector<SearchSpec> &C_specs, const SymbolContext &sc) { - for (const SearchSpec &C_spec : C_specs) { - ConstString name = C_spec.name; + llvm::Optional<lldb::addr_t> Resolve(SymbolContextList &sc_list) { + if (sc_list.IsEmpty()) + return llvm::None; - if (CPlusPlusLanguage::IsCPPMangledName(name.GetCString())) { - Mangled mangled(name); - ConstString demangled = mangled.GetDemangledName(); - - if (demangled) { - ConstString best_alternate_mangled_name = - FindBestAlternateMangledName(demangled, sc); + lldb::addr_t load_address = LLDB_INVALID_ADDRESS; - if (best_alternate_mangled_name) { - CPP_specs.push_back(best_alternate_mangled_name); + // Missing_weak_symbol will be true only if we found only weak undefined + // references to this symbol. + m_symbol_was_missing_weak = true; + + for (auto candidate_sc : sc_list.SymbolContexts()) { + // Only symbols can be weak undefined. + if (!candidate_sc.symbol || + candidate_sc.symbol->GetType() != lldb::eSymbolTypeUndefined || + !candidate_sc.symbol->IsWeak()) + m_symbol_was_missing_weak = false; + + // First try the symbol. + if (candidate_sc.symbol) { + load_address = candidate_sc.symbol->ResolveCallableAddress(*m_target); + if (load_address == LLDB_INVALID_ADDRESS) { + Address addr = candidate_sc.symbol->GetAddress(); + load_address = m_target->GetProcessSP() + ? addr.GetLoadAddress(m_target) + : addr.GetFileAddress(); } } - } - std::set<ConstString> alternates; - CPlusPlusLanguage::FindAlternateFunctionManglings(name, alternates); - CPP_specs.insert(CPP_specs.end(), alternates.begin(), alternates.end()); - } -} - -void IRExecutionUnit::CollectFallbackNames( - std::vector<SearchSpec> &fallback_specs, - const std::vector<SearchSpec> &C_specs) { - // As a last-ditch fallback, try the base name for C++ names. It's terrible, - // but the DWARF doesn't always encode "extern C" correctly. + // If that didn't work, try the function. + if (load_address == LLDB_INVALID_ADDRESS && candidate_sc.function) { + Address addr = + candidate_sc.function->GetAddressRange().GetBaseAddress(); + load_address = m_target->GetProcessSP() ? addr.GetLoadAddress(m_target) + : addr.GetFileAddress(); + } - for (const SearchSpec &C_spec : C_specs) { - ConstString name = C_spec.name; + // We found a load address. + if (load_address != LLDB_INVALID_ADDRESS) { + // If the load address is external, we're done. + const bool is_external = + (candidate_sc.function) || + (candidate_sc.symbol && candidate_sc.symbol->IsExternal()); + if (is_external) + return load_address; - if (!CPlusPlusLanguage::IsCPPMangledName(name.GetCString())) - continue; + // Otherwise, remember the best internal load address. + if (m_best_internal_load_address == LLDB_INVALID_ADDRESS) + m_best_internal_load_address = load_address; + } + } - Mangled mangled_name(name); - ConstString demangled_name = mangled_name.GetDemangledName(); - if (demangled_name.IsEmpty()) - continue; + // You test the address of a weak symbol against NULL to see if it is + // present. So we should return 0 for a missing weak symbol. + if (m_symbol_was_missing_weak) + return 0; - const char *demangled_cstr = demangled_name.AsCString(); - const char *lparen_loc = strchr(demangled_cstr, '('); - if (!lparen_loc) - continue; + return llvm::None; + } - llvm::StringRef base_name(demangled_cstr, - lparen_loc - demangled_cstr); - fallback_specs.push_back(ConstString(base_name)); + lldb::addr_t GetBestInternalLoadAddress() const { + return m_best_internal_load_address; } -} -lldb::addr_t IRExecutionUnit::FindInSymbols( - const std::vector<IRExecutionUnit::SearchSpec> &specs, - const lldb_private::SymbolContext &sc, - bool &symbol_was_missing_weak) { +private: + Target *m_target; + bool &m_symbol_was_missing_weak; + lldb::addr_t m_best_internal_load_address = LLDB_INVALID_ADDRESS; +}; + +lldb::addr_t +IRExecutionUnit::FindInSymbols(const std::vector<ConstString> &names, + const lldb_private::SymbolContext &sc, + bool &symbol_was_missing_weak) { symbol_was_missing_weak = false; - Target *target = sc.target_sp.get(); + Target *target = sc.target_sp.get(); if (!target) { - // we shouldn't be doing any symbol lookup at all without a target + // We shouldn't be doing any symbol lookup at all without a target. return LLDB_INVALID_ADDRESS; } - for (const SearchSpec &spec : specs) { - SymbolContextList sc_list; - - lldb::addr_t best_internal_load_address = LLDB_INVALID_ADDRESS; - - std::function<bool(lldb::addr_t &, SymbolContextList &, - const lldb_private::SymbolContext &)> - get_external_load_address = [&best_internal_load_address, target, - &symbol_was_missing_weak]( - lldb::addr_t &load_address, SymbolContextList &sc_list, - const lldb_private::SymbolContext &sc) -> lldb::addr_t { - load_address = LLDB_INVALID_ADDRESS; - - if (sc_list.GetSize() == 0) - return false; - - // missing_weak_symbol will be true only if we found only weak undefined - // references to this symbol. - symbol_was_missing_weak = true; - for (auto candidate_sc : sc_list.SymbolContexts()) { - // Only symbols can be weak undefined: - if (!candidate_sc.symbol) - symbol_was_missing_weak = false; - else if (candidate_sc.symbol->GetType() != lldb::eSymbolTypeUndefined - || !candidate_sc.symbol->IsWeak()) - symbol_was_missing_weak = false; - - const bool is_external = - (candidate_sc.function) || - (candidate_sc.symbol && candidate_sc.symbol->IsExternal()); - if (candidate_sc.symbol) { - load_address = candidate_sc.symbol->ResolveCallableAddress(*target); - - if (load_address == LLDB_INVALID_ADDRESS) { - if (target->GetProcessSP()) - load_address = - candidate_sc.symbol->GetAddress().GetLoadAddress(target); - else - load_address = candidate_sc.symbol->GetAddress().GetFileAddress(); - } - } - - if (load_address == LLDB_INVALID_ADDRESS && candidate_sc.function) { - if (target->GetProcessSP()) - load_address = candidate_sc.function->GetAddressRange() - .GetBaseAddress() - .GetLoadAddress(target); - else - load_address = candidate_sc.function->GetAddressRange() - .GetBaseAddress() - .GetFileAddress(); - } + LoadAddressResolver resolver(target, symbol_was_missing_weak); - if (load_address != LLDB_INVALID_ADDRESS) { - if (is_external) { - return true; - } else if (best_internal_load_address == LLDB_INVALID_ADDRESS) { - best_internal_load_address = load_address; - load_address = LLDB_INVALID_ADDRESS; - } - } - } - - // You test the address of a weak symbol against NULL to see if it is - // present. So we should return 0 for a missing weak symbol. - if (symbol_was_missing_weak) { - load_address = 0; - return true; - } - - return false; - }; + ModuleFunctionSearchOptions function_options; + function_options.include_symbols = true; + function_options.include_inlines = false; + for (const ConstString &name : names) { if (sc.module_sp) { - sc.module_sp->FindFunctions(spec.name, CompilerDeclContext(), spec.mask, - true, // include_symbols - false, // include_inlines + SymbolContextList sc_list; + sc.module_sp->FindFunctions(name, CompilerDeclContext(), + lldb::eFunctionNameTypeFull, function_options, sc_list); + if (auto load_addr = resolver.Resolve(sc_list)) + return *load_addr; } - lldb::addr_t load_address = LLDB_INVALID_ADDRESS; - - if (get_external_load_address(load_address, sc_list, sc)) { - return load_address; - } else { - sc_list.Clear(); - } - - if (sc_list.GetSize() == 0 && sc.target_sp) { - sc.target_sp->GetImages().FindFunctions(spec.name, spec.mask, - true, // include_symbols - false, // include_inlines - sc_list); + if (sc.target_sp) { + SymbolContextList sc_list; + sc.target_sp->GetImages().FindFunctions(name, lldb::eFunctionNameTypeFull, + function_options, sc_list); + if (auto load_addr = resolver.Resolve(sc_list)) + return *load_addr; } - if (get_external_load_address(load_address, sc_list, sc)) { - return load_address; - } else { - sc_list.Clear(); - } - - if (sc_list.GetSize() == 0 && sc.target_sp) { + if (sc.target_sp) { + SymbolContextList sc_list; sc.target_sp->GetImages().FindSymbolsWithNameAndType( - spec.name, lldb::eSymbolTypeAny, sc_list); - } - - if (get_external_load_address(load_address, sc_list, sc)) { - return load_address; + name, lldb::eSymbolTypeAny, sc_list); + if (auto load_addr = resolver.Resolve(sc_list)) + return *load_addr; } - // if there are any searches we try after this, add an sc_list.Clear() in - // an "else" clause here - if (best_internal_load_address != LLDB_INVALID_ADDRESS) { + lldb::addr_t best_internal_load_address = + resolver.GetBestInternalLoadAddress(); + if (best_internal_load_address != LLDB_INVALID_ADDRESS) return best_internal_load_address; - } } return LLDB_INVALID_ADDRESS; } lldb::addr_t -IRExecutionUnit::FindInRuntimes(const std::vector<SearchSpec> &specs, +IRExecutionUnit::FindInRuntimes(const std::vector<ConstString> &names, const lldb_private::SymbolContext &sc) { lldb::TargetSP target_sp = sc.target_sp; @@ -916,9 +827,9 @@ IRExecutionUnit::FindInRuntimes(const std::vector<SearchSpec> &specs, return LLDB_INVALID_ADDRESS; } - for (const SearchSpec &spec : specs) { + for (const ConstString &name : names) { for (LanguageRuntime *runtime : process_sp->GetLanguageRuntimes()) { - lldb::addr_t symbol_load_addr = runtime->LookupRuntimeSymbol(spec.name); + lldb::addr_t symbol_load_addr = runtime->LookupRuntimeSymbol(name); if (symbol_load_addr != LLDB_INVALID_ADDRESS) return symbol_load_addr; @@ -929,12 +840,12 @@ IRExecutionUnit::FindInRuntimes(const std::vector<SearchSpec> &specs, } lldb::addr_t IRExecutionUnit::FindInUserDefinedSymbols( - const std::vector<SearchSpec> &specs, + const std::vector<ConstString> &names, const lldb_private::SymbolContext &sc) { lldb::TargetSP target_sp = sc.target_sp; - for (const SearchSpec &spec : specs) { - lldb::addr_t symbol_load_addr = target_sp->GetPersistentSymbol(spec.name); + for (const ConstString &name : names) { + lldb::addr_t symbol_load_addr = target_sp->GetPersistentSymbol(name); if (symbol_load_addr != LLDB_INVALID_ADDRESS) return symbol_load_addr; @@ -943,18 +854,18 @@ lldb::addr_t IRExecutionUnit::FindInUserDefinedSymbols( return LLDB_INVALID_ADDRESS; } -lldb::addr_t -IRExecutionUnit::FindSymbol(lldb_private::ConstString name, bool &missing_weak) { - std::vector<SearchSpec> candidate_C_names; - std::vector<SearchSpec> candidate_CPlusPlus_names; +lldb::addr_t IRExecutionUnit::FindSymbol(lldb_private::ConstString name, + bool &missing_weak) { + std::vector<ConstString> candidate_C_names; + std::vector<ConstString> candidate_CPlusPlus_names; CollectCandidateCNames(candidate_C_names, name); - + lldb::addr_t ret = FindInSymbols(candidate_C_names, m_sym_ctx, missing_weak); if (ret != LLDB_INVALID_ADDRESS) return ret; - - // If we find the symbol in runtimes or user defined symbols it can't be + + // If we find the symbol in runtimes or user defined symbols it can't be // a missing weak symbol. missing_weak = false; ret = FindInRuntimes(candidate_C_names, m_sym_ctx); @@ -968,14 +879,6 @@ IRExecutionUnit::FindSymbol(lldb_private::ConstString name, bool &missing_weak) CollectCandidateCPlusPlusNames(candidate_CPlusPlus_names, candidate_C_names, m_sym_ctx); ret = FindInSymbols(candidate_CPlusPlus_names, m_sym_ctx, missing_weak); - if (ret != LLDB_INVALID_ADDRESS) - return ret; - - std::vector<SearchSpec> candidate_fallback_names; - - CollectFallbackNames(candidate_fallback_names, candidate_C_names); - ret = FindInSymbols(candidate_fallback_names, m_sym_ctx, missing_weak); - return ret; } diff --git a/contrib/llvm-project/lldb/source/Expression/IRInterpreter.cpp b/contrib/llvm-project/lldb/source/Expression/IRInterpreter.cpp index 788520d1f32b..9b2af56dfc8a 100644 --- a/contrib/llvm-project/lldb/source/Expression/IRInterpreter.cpp +++ b/contrib/llvm-project/lldb/source/Expression/IRInterpreter.cpp @@ -1398,7 +1398,7 @@ bool IRInterpreter::Interpret(llvm::Module &module, llvm::Function &function, } // Find number of arguments - const int numArgs = call_inst->getNumArgOperands(); + const int numArgs = call_inst->arg_size(); // We work with a fixed array of 16 arguments which is our upper limit static lldb_private::ABI::CallArgument rawArgs[16]; diff --git a/contrib/llvm-project/lldb/source/Expression/REPL.cpp b/contrib/llvm-project/lldb/source/Expression/REPL.cpp index c3d14960f74c..9cd6129eedd7 100644 --- a/contrib/llvm-project/lldb/source/Expression/REPL.cpp +++ b/contrib/llvm-project/lldb/source/Expression/REPL.cpp @@ -445,7 +445,7 @@ void REPL::IOHandlerInputComplete(IOHandler &io_handler, std::string &code) { if (!m_repl_source_path.empty()) { auto file = FileSystem::Instance().Open( FileSpec(m_repl_source_path), - File::eOpenOptionWrite | File::eOpenOptionTruncate | + File::eOpenOptionWriteOnly | File::eOpenOptionTruncate | File::eOpenOptionCanCreate, lldb::eFilePermissionsFileDefault); if (file) { diff --git a/contrib/llvm-project/lldb/source/Expression/UserExpression.cpp b/contrib/llvm-project/lldb/source/Expression/UserExpression.cpp index eac89c24bc1e..b61781c0b82b 100644 --- a/contrib/llvm-project/lldb/source/Expression/UserExpression.cpp +++ b/contrib/llvm-project/lldb/source/Expression/UserExpression.cpp @@ -6,12 +6,8 @@ // //===----------------------------------------------------------------------===// -#include "lldb/Host/Config.h" - #include <cstdio> -#if HAVE_SYS_TYPES_H #include <sys/types.h> -#endif #include <cstdlib> #include <map> diff --git a/contrib/llvm-project/lldb/source/Expression/UtilityFunction.cpp b/contrib/llvm-project/lldb/source/Expression/UtilityFunction.cpp index d7a89a8e1446..1a4df9722706 100644 --- a/contrib/llvm-project/lldb/source/Expression/UtilityFunction.cpp +++ b/contrib/llvm-project/lldb/source/Expression/UtilityFunction.cpp @@ -6,13 +6,8 @@ // //===----------------------------------------------------------------------===// -#include "lldb/Host/Config.h" - #include <cstdio> -#if HAVE_SYS_TYPES_H #include <sys/types.h> -#endif - #include "lldb/Core/Module.h" #include "lldb/Core/StreamFile.h" diff --git a/contrib/llvm-project/lldb/source/Host/common/Editline.cpp b/contrib/llvm-project/lldb/source/Host/common/Editline.cpp index a5598c387b8c..6898f8452161 100644 --- a/contrib/llvm-project/lldb/source/Host/common/Editline.cpp +++ b/contrib/llvm-project/lldb/source/Host/common/Editline.cpp @@ -205,7 +205,7 @@ private: // Use static GetHistory() function to get a EditlineHistorySP to one of // these objects EditlineHistory(const std::string &prefix, uint32_t size, bool unique_entries) - : m_history(nullptr), m_event(), m_prefix(prefix), m_path() { + : m_prefix(prefix) { m_history = history_winit(); history_w(m_history, &m_event, H_SETSIZE, size); if (unique_entries) @@ -298,11 +298,15 @@ public: } protected: - HistoryW *m_history; // The history object - HistEventW m_event; // The history event needed to contain all history events - std::string m_prefix; // The prefix name (usually the editline program name) - // to use when loading/saving history - std::string m_path; // Path to the history file + /// The history object. + HistoryW *m_history = nullptr; + /// The history event needed to contain all history events. + HistEventW m_event; + /// The prefix name (usually the editline program name) to use when + /// loading/saving history. + std::string m_prefix; + /// Path to the history file. + std::string m_path; }; } } @@ -1006,11 +1010,11 @@ unsigned char Editline::TabCommand(int ch) { switch (completion.GetMode()) { case CompletionMode::Normal: { std::string to_add = completion.GetCompletion(); - to_add = to_add.substr(request.GetCursorArgumentPrefix().size()); // Terminate the current argument with a quote if it started with a quote. if (!request.GetParsedLine().empty() && request.GetParsedArg().IsQuoted()) to_add.push_back(request.GetParsedArg().GetQuoteChar()); to_add.push_back(' '); + el_deletestr(m_editline, request.GetCursorArgumentPrefix().size()); el_insertstr(m_editline, to_add.c_str()); // Clear all the autosuggestion parts if the only single space can be completed. if (to_add == " ") @@ -1554,8 +1558,10 @@ bool Editline::GetLines(int first_line_number, StringList &lines, interrupted = m_editor_status == EditorStatus::Interrupted; if (!interrupted) { - // Save the completed entry in history before returning - m_history_sp->Enter(CombineLines(m_input_lines).c_str()); + // Save the completed entry in history before returning. Don't save empty + // input as that just clutters the command history. + if (!m_input_lines.empty()) + m_history_sp->Enter(CombineLines(m_input_lines).c_str()); lines = GetInputAsStringList(); } diff --git a/contrib/llvm-project/lldb/source/Host/common/File.cpp b/contrib/llvm-project/lldb/source/Host/common/File.cpp index e302e0a0de09..daac1fef2f36 100644 --- a/contrib/llvm-project/lldb/source/Host/common/File.cpp +++ b/contrib/llvm-project/lldb/source/Host/common/File.cpp @@ -41,20 +41,23 @@ using llvm::Expected; Expected<const char *> File::GetStreamOpenModeFromOptions(File::OpenOptions options) { + File::OpenOptions rw = + options & (File::eOpenOptionReadOnly | File::eOpenOptionWriteOnly | + File::eOpenOptionReadWrite); + if (options & File::eOpenOptionAppend) { - if (options & File::eOpenOptionRead) { + if (rw == File::eOpenOptionReadWrite) { if (options & File::eOpenOptionCanCreateNewOnly) return "a+x"; else return "a+"; - } else if (options & File::eOpenOptionWrite) { + } else if (rw == File::eOpenOptionWriteOnly) { if (options & File::eOpenOptionCanCreateNewOnly) return "ax"; else return "a"; } - } else if (options & File::eOpenOptionRead && - options & File::eOpenOptionWrite) { + } else if (rw == File::eOpenOptionReadWrite) { if (options & File::eOpenOptionCanCreate) { if (options & File::eOpenOptionCanCreateNewOnly) return "w+x"; @@ -62,10 +65,10 @@ File::GetStreamOpenModeFromOptions(File::OpenOptions options) { return "w+"; } else return "r+"; - } else if (options & File::eOpenOptionRead) { - return "r"; - } else if (options & File::eOpenOptionWrite) { + } else if (rw == File::eOpenOptionWriteOnly) { return "w"; + } else if (rw == File::eOpenOptionReadOnly) { + return "r"; } return llvm::createStringError( llvm::inconvertibleErrorCode(), @@ -75,19 +78,20 @@ File::GetStreamOpenModeFromOptions(File::OpenOptions options) { Expected<File::OpenOptions> File::GetOptionsFromMode(llvm::StringRef mode) { OpenOptions opts = llvm::StringSwitch<OpenOptions>(mode) - .Cases("r", "rb", eOpenOptionRead) - .Cases("w", "wb", eOpenOptionWrite) + .Cases("r", "rb", eOpenOptionReadOnly) + .Cases("w", "wb", eOpenOptionWriteOnly) .Cases("a", "ab", - eOpenOptionWrite | eOpenOptionAppend | eOpenOptionCanCreate) - .Cases("r+", "rb+", "r+b", eOpenOptionRead | eOpenOptionWrite) + eOpenOptionWriteOnly | eOpenOptionAppend | + eOpenOptionCanCreate) + .Cases("r+", "rb+", "r+b", eOpenOptionReadWrite) .Cases("w+", "wb+", "w+b", - eOpenOptionRead | eOpenOptionWrite | eOpenOptionCanCreate | - eOpenOptionTruncate) + eOpenOptionReadWrite | eOpenOptionCanCreate | + eOpenOptionTruncate) .Cases("a+", "ab+", "a+b", - eOpenOptionRead | eOpenOptionWrite | eOpenOptionAppend | + eOpenOptionReadWrite | eOpenOptionAppend | eOpenOptionCanCreate) - .Default(OpenOptions()); - if (opts) + .Default(eOpenOptionInvalid); + if (opts != eOpenOptionInvalid) return opts; return llvm::createStringError( llvm::inconvertibleErrorCode(), @@ -310,9 +314,15 @@ Status NativeFile::Close() { if (m_own_stream) { if (::fclose(m_stream) == EOF) error.SetErrorToErrno(); - } else if (m_options & eOpenOptionWrite) { - if (::fflush(m_stream) == EOF) - error.SetErrorToErrno(); + } else { + File::OpenOptions rw = + m_options & (File::eOpenOptionReadOnly | File::eOpenOptionWriteOnly | + File::eOpenOptionReadWrite); + + if (rw == eOpenOptionWriteOnly || rw == eOpenOptionReadWrite) { + if (::fflush(m_stream) == EOF) + error.SetErrorToErrno(); + } } } if (DescriptorIsValid() && m_own_descriptor) { @@ -732,10 +742,15 @@ size_t NativeFile::PrintfVarArg(const char *format, va_list args) { mode_t File::ConvertOpenOptionsForPOSIXOpen(OpenOptions open_options) { mode_t mode = 0; - if (open_options & eOpenOptionRead && open_options & eOpenOptionWrite) + File::OpenOptions rw = + open_options & (File::eOpenOptionReadOnly | File::eOpenOptionWriteOnly | + File::eOpenOptionReadWrite); + if (rw == eOpenOptionReadWrite) mode |= O_RDWR; - else if (open_options & eOpenOptionWrite) + else if (rw == eOpenOptionWriteOnly) mode |= O_WRONLY; + else if (rw == eOpenOptionReadOnly) + mode |= O_RDONLY; if (open_options & eOpenOptionAppend) mode |= O_APPEND; @@ -754,5 +769,107 @@ mode_t File::ConvertOpenOptionsForPOSIXOpen(OpenOptions open_options) { return mode; } +llvm::Expected<SerialPort::Options> +SerialPort::OptionsFromURL(llvm::StringRef urlqs) { + SerialPort::Options serial_options; + for (llvm::StringRef x : llvm::split(urlqs, '&')) { + if (x.consume_front("baud=")) { + unsigned int baud_rate; + if (!llvm::to_integer(x, baud_rate, 10)) + return llvm::createStringError(llvm::inconvertibleErrorCode(), + "Invalid baud rate: %s", + x.str().c_str()); + serial_options.BaudRate = baud_rate; + } else if (x.consume_front("parity=")) { + serial_options.Parity = + llvm::StringSwitch<llvm::Optional<Terminal::Parity>>(x) + .Case("no", Terminal::Parity::No) + .Case("even", Terminal::Parity::Even) + .Case("odd", Terminal::Parity::Odd) + .Case("mark", Terminal::Parity::Mark) + .Case("space", Terminal::Parity::Space) + .Default(llvm::None); + if (!serial_options.Parity) + return llvm::createStringError( + llvm::inconvertibleErrorCode(), + "Invalid parity (must be no, even, odd, mark or space): %s", + x.str().c_str()); + } else if (x.consume_front("parity-check=")) { + serial_options.ParityCheck = + llvm::StringSwitch<llvm::Optional<Terminal::ParityCheck>>(x) + .Case("no", Terminal::ParityCheck::No) + .Case("replace", Terminal::ParityCheck::ReplaceWithNUL) + .Case("ignore", Terminal::ParityCheck::Ignore) + // "mark" mode is not currently supported as it requires special + // input processing + // .Case("mark", Terminal::ParityCheck::Mark) + .Default(llvm::None); + if (!serial_options.ParityCheck) + return llvm::createStringError( + llvm::inconvertibleErrorCode(), + "Invalid parity-check (must be no, replace, ignore or mark): %s", + x.str().c_str()); + } else if (x.consume_front("stop-bits=")) { + unsigned int stop_bits; + if (!llvm::to_integer(x, stop_bits, 10) || + (stop_bits != 1 && stop_bits != 2)) + return llvm::createStringError( + llvm::inconvertibleErrorCode(), + "Invalid stop bit number (must be 1 or 2): %s", x.str().c_str()); + serial_options.StopBits = stop_bits; + } else + return llvm::createStringError(llvm::inconvertibleErrorCode(), + "Unknown parameter: %s", x.str().c_str()); + } + return serial_options; +} + +llvm::Expected<std::unique_ptr<SerialPort>> +SerialPort::Create(int fd, OpenOptions options, Options serial_options, + bool transfer_ownership) { + std::unique_ptr<SerialPort> out{ + new SerialPort(fd, options, serial_options, transfer_ownership)}; + + if (!out->GetIsInteractive()) + return llvm::createStringError(llvm::inconvertibleErrorCode(), + "the specified file is not a teletype"); + + Terminal term{fd}; + if (llvm::Error error = term.SetRaw()) + return std::move(error); + if (serial_options.BaudRate) { + if (llvm::Error error = + term.SetBaudRate(serial_options.BaudRate.getValue())) + return std::move(error); + } + if (serial_options.Parity) { + if (llvm::Error error = term.SetParity(serial_options.Parity.getValue())) + return std::move(error); + } + if (serial_options.ParityCheck) { + if (llvm::Error error = + term.SetParityCheck(serial_options.ParityCheck.getValue())) + return std::move(error); + } + if (serial_options.StopBits) { + if (llvm::Error error = + term.SetStopBits(serial_options.StopBits.getValue())) + return std::move(error); + } + + return std::move(out); +} + +SerialPort::SerialPort(int fd, OpenOptions options, + SerialPort::Options serial_options, + bool transfer_ownership) + : NativeFile(fd, options, transfer_ownership), m_state(fd) {} + +Status SerialPort::Close() { + m_state.Restore(); + return NativeFile::Close(); +} + char File::ID = 0; char NativeFile::ID = 0; +char SerialPort::ID = 0; diff --git a/contrib/llvm-project/lldb/source/Host/common/FileSystem.cpp b/contrib/llvm-project/lldb/source/Host/common/FileSystem.cpp index a2c3b3556a6c..7687ad6c20a6 100644 --- a/contrib/llvm-project/lldb/source/Host/common/FileSystem.cpp +++ b/contrib/llvm-project/lldb/source/Host/common/FileSystem.cpp @@ -381,13 +381,13 @@ static int OpenWithFS(const FileSystem &fs, const char *path, int flags, return const_cast<FileSystem &>(fs).Open(path, flags, mode); } -static int GetOpenFlags(uint32_t options) { - const bool read = options & File::eOpenOptionRead; - const bool write = options & File::eOpenOptionWrite; - +static int GetOpenFlags(File::OpenOptions options) { int open_flags = 0; - if (write) { - if (read) + File::OpenOptions rw = + options & (File::eOpenOptionReadOnly | File::eOpenOptionWriteOnly | + File::eOpenOptionReadWrite); + if (rw == File::eOpenOptionWriteOnly || rw == File::eOpenOptionReadWrite) { + if (rw == File::eOpenOptionReadWrite) open_flags |= O_RDWR; else open_flags |= O_WRONLY; @@ -403,7 +403,7 @@ static int GetOpenFlags(uint32_t options) { if (options & File::eOpenOptionCanCreateNewOnly) open_flags |= O_CREAT | O_EXCL; - } else if (read) { + } else if (rw == File::eOpenOptionReadOnly) { open_flags |= O_RDONLY; #ifndef _WIN32 diff --git a/contrib/llvm-project/lldb/source/Host/common/LockFileBase.cpp b/contrib/llvm-project/lldb/source/Host/common/LockFileBase.cpp index d4cd8f7ffed1..1c0de9e04e29 100644 --- a/contrib/llvm-project/lldb/source/Host/common/LockFileBase.cpp +++ b/contrib/llvm-project/lldb/source/Host/common/LockFileBase.cpp @@ -11,12 +11,9 @@ using namespace lldb; using namespace lldb_private; -namespace { +static Status AlreadyLocked() { return Status("Already locked"); } -Status AlreadyLocked() { return Status("Already locked"); } - -Status NotLocked() { return Status("Not locked"); } -} +static Status NotLocked() { return Status("Not locked"); } LockFileBase::LockFileBase(int fd) : m_fd(fd), m_locked(false), m_start(0), m_len(0) {} diff --git a/contrib/llvm-project/lldb/source/Host/common/NativeRegisterContext.cpp b/contrib/llvm-project/lldb/source/Host/common/NativeRegisterContext.cpp index 04d10aba4e63..d0afc2b47dac 100644 --- a/contrib/llvm-project/lldb/source/Host/common/NativeRegisterContext.cpp +++ b/contrib/llvm-project/lldb/source/Host/common/NativeRegisterContext.cpp @@ -56,6 +56,17 @@ NativeRegisterContext::GetRegisterInfoByName(llvm::StringRef reg_name, if (reg_name.empty()) return nullptr; + // Generic register names take precedence over specific register names. + // For example, on x86 we want "sp" to refer to the complete RSP/ESP register + // rather than the 16-bit SP pseudo-register. + uint32_t generic_reg = Args::StringToGenericRegister(reg_name); + if (generic_reg != LLDB_INVALID_REGNUM) { + const RegisterInfo *reg_info = + GetRegisterInfo(eRegisterKindGeneric, generic_reg); + if (reg_info) + return reg_info; + } + const uint32_t num_registers = GetRegisterCount(); for (uint32_t reg = start_idx; reg < num_registers; ++reg) { const RegisterInfo *reg_info = GetRegisterInfoAtIndex(reg); @@ -64,6 +75,7 @@ NativeRegisterContext::GetRegisterInfoByName(llvm::StringRef reg_name, reg_name.equals_insensitive(reg_info->alt_name)) return reg_info; } + return nullptr; } diff --git a/contrib/llvm-project/lldb/source/Host/common/Socket.cpp b/contrib/llvm-project/lldb/source/Host/common/Socket.cpp index d1c327dcb790..cc0659797530 100644 --- a/contrib/llvm-project/lldb/source/Host/common/Socket.cpp +++ b/contrib/llvm-project/lldb/source/Host/common/Socket.cpp @@ -11,11 +11,9 @@ #include "lldb/Host/Config.h" #include "lldb/Host/Host.h" #include "lldb/Host/SocketAddress.h" -#include "lldb/Host/StringConvert.h" #include "lldb/Host/common/TCPSocket.h" #include "lldb/Host/common/UDPSocket.h" #include "lldb/Utility/Log.h" -#include "lldb/Utility/RegularExpression.h" #include "llvm/ADT/STLExtras.h" #include "llvm/Support/Errno.h" @@ -61,16 +59,13 @@ typedef void *get_socket_option_arg_type; const NativeSocket Socket::kInvalidSocketValue = -1; #endif // #if defined(_WIN32) -namespace { - -bool IsInterrupted() { +static bool IsInterrupted() { #if defined(_WIN32) return ::WSAGetLastError() == WSAEINTR; #else return errno == EINTR; #endif } -} Socket::Socket(SocketProtocol protocol, bool should_close, bool child_processes_inherit) @@ -168,37 +163,17 @@ Socket::TcpConnect(llvm::StringRef host_and_port, llvm::Expected<std::unique_ptr<TCPSocket>> Socket::TcpListen(llvm::StringRef host_and_port, bool child_processes_inherit, - Predicate<uint16_t> *predicate, int backlog) { + int backlog) { Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_CONNECTION)); LLDB_LOG(log, "host_and_port = {0}", host_and_port); - Status error; - std::string host_str; - std::string port_str; - int32_t port = INT32_MIN; - if (!DecodeHostAndPort(host_and_port, host_str, port_str, port, &error)) - return error.ToError(); - std::unique_ptr<TCPSocket> listen_socket( new TCPSocket(true, child_processes_inherit)); - error = listen_socket->Listen(host_and_port, backlog); + Status error = listen_socket->Listen(host_and_port, backlog); if (error.Fail()) return error.ToError(); - // We were asked to listen on port zero which means we must now read the - // actual port that was given to us as port zero is a special code for - // "find an open port for me". - if (port == 0) - port = listen_socket->GetLocalPortNumber(); - - // Set the port predicate since when doing a listen://<host>:<port> it - // often needs to accept the incoming connection which is a blocking system - // call. Allowing access to the bound port using a predicate allows us to - // wait for the port predicate to be set to a non-zero value from another - // thread in an efficient manor. - if (predicate) - predicate->SetValue(port, eBroadcastAlways); return std::move(listen_socket); } @@ -208,111 +183,27 @@ Socket::UdpConnect(llvm::StringRef host_and_port, return UDPSocket::Connect(host_and_port, child_processes_inherit); } -Status Socket::UnixDomainConnect(llvm::StringRef name, - bool child_processes_inherit, - Socket *&socket) { - Status error; - std::unique_ptr<Socket> connect_socket( - Create(ProtocolUnixDomain, child_processes_inherit, error)); - if (error.Fail()) - return error; - - error = connect_socket->Connect(name); - if (error.Success()) - socket = connect_socket.release(); - - return error; -} - -Status Socket::UnixDomainAccept(llvm::StringRef name, - bool child_processes_inherit, Socket *&socket) { - Status error; - std::unique_ptr<Socket> listen_socket( - Create(ProtocolUnixDomain, child_processes_inherit, error)); - if (error.Fail()) - return error; - - error = listen_socket->Listen(name, 5); - if (error.Fail()) - return error; - - error = listen_socket->Accept(socket); - return error; -} - -Status Socket::UnixAbstractConnect(llvm::StringRef name, - bool child_processes_inherit, - Socket *&socket) { - Status error; - std::unique_ptr<Socket> connect_socket( - Create(ProtocolUnixAbstract, child_processes_inherit, error)); - if (error.Fail()) - return error; - - error = connect_socket->Connect(name); - if (error.Success()) - socket = connect_socket.release(); - return error; -} - -Status Socket::UnixAbstractAccept(llvm::StringRef name, - bool child_processes_inherit, - Socket *&socket) { - Status error; - std::unique_ptr<Socket> listen_socket( - Create(ProtocolUnixAbstract, child_processes_inherit, error)); - if (error.Fail()) - return error; - - error = listen_socket->Listen(name, 5); - if (error.Fail()) - return error; - - error = listen_socket->Accept(socket); - return error; -} - -bool Socket::DecodeHostAndPort(llvm::StringRef host_and_port, - std::string &host_str, std::string &port_str, - int32_t &port, Status *error_ptr) { - static RegularExpression g_regex( - llvm::StringRef("([^:]+|\\[[0-9a-fA-F:]+.*\\]):([0-9]+)")); +llvm::Expected<Socket::HostAndPort> Socket::DecodeHostAndPort(llvm::StringRef host_and_port) { + static llvm::Regex g_regex("([^:]+|\\[[0-9a-fA-F:]+.*\\]):([0-9]+)"); + HostAndPort ret; llvm::SmallVector<llvm::StringRef, 3> matches; - if (g_regex.Execute(host_and_port, &matches)) { - host_str = matches[1].str(); - port_str = matches[2].str(); + if (g_regex.match(host_and_port, &matches)) { + ret.hostname = matches[1].str(); // IPv6 addresses are wrapped in [] when specified with ports - if (host_str.front() == '[' && host_str.back() == ']') - host_str = host_str.substr(1, host_str.size() - 2); - bool ok = false; - port = StringConvert::ToUInt32(port_str.c_str(), UINT32_MAX, 10, &ok); - if (ok && port <= UINT16_MAX) { - if (error_ptr) - error_ptr->Clear(); - return true; - } - // port is too large - if (error_ptr) - error_ptr->SetErrorStringWithFormat( - "invalid host:port specification: '%s'", host_and_port.str().c_str()); - return false; - } - - // If this was unsuccessful, then check if it's simply a signed 32-bit - // integer, representing a port with an empty host. - host_str.clear(); - port_str.clear(); - if (to_integer(host_and_port, port, 10) && port < UINT16_MAX) { - port_str = std::string(host_and_port); - if (error_ptr) - error_ptr->Clear(); - return true; + if (ret.hostname.front() == '[' && ret.hostname.back() == ']') + ret.hostname = ret.hostname.substr(1, ret.hostname.size() - 2); + if (to_integer(matches[2], ret.port, 10)) + return ret; + } else { + // If this was unsuccessful, then check if it's simply an unsigned 16-bit + // integer, representing a port with an empty host. + if (to_integer(host_and_port, ret.port, 10)) + return ret; } - if (error_ptr) - error_ptr->SetErrorStringWithFormat("invalid host:port specification: '%s'", - host_and_port.str().c_str()); - return false; + return llvm::createStringError(llvm::inconvertibleErrorCode(), + "invalid host:port specification: '%s'", + host_and_port.str().c_str()); } IOObject::WaitableHandle Socket::GetWaitableHandle() { @@ -481,3 +372,8 @@ NativeSocket Socket::AcceptSocket(NativeSocket sockfd, struct sockaddr *addr, SetLastError(error); return fd; } + +llvm::raw_ostream &lldb_private::operator<<(llvm::raw_ostream &OS, + const Socket::HostAndPort &HP) { + return OS << '[' << HP.hostname << ']' << ':' << HP.port; +} diff --git a/contrib/llvm-project/lldb/source/Host/common/StringConvert.cpp b/contrib/llvm-project/lldb/source/Host/common/StringConvert.cpp deleted file mode 100644 index b4eb92755367..000000000000 --- a/contrib/llvm-project/lldb/source/Host/common/StringConvert.cpp +++ /dev/null @@ -1,95 +0,0 @@ -//===-- StringConvert.cpp -------------------------------------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#include <cstdlib> - -#include "lldb/Host/StringConvert.h" - -namespace lldb_private { -namespace StringConvert { - -int32_t ToSInt32(const char *s, int32_t fail_value, int base, - bool *success_ptr) { - if (s && s[0]) { - char *end = nullptr; - const long sval = ::strtol(s, &end, base); - if (*end == '\0') { - if (success_ptr) - *success_ptr = ((sval <= INT32_MAX) && (sval >= INT32_MIN)); - return (int32_t)sval; // All characters were used, return the result - } - } - if (success_ptr) - *success_ptr = false; - return fail_value; -} - -uint32_t ToUInt32(const char *s, uint32_t fail_value, int base, - bool *success_ptr) { - if (s && s[0]) { - char *end = nullptr; - const unsigned long uval = ::strtoul(s, &end, base); - if (*end == '\0') { - if (success_ptr) - *success_ptr = (uval <= UINT32_MAX); - return (uint32_t)uval; // All characters were used, return the result - } - } - if (success_ptr) - *success_ptr = false; - return fail_value; -} - -int64_t ToSInt64(const char *s, int64_t fail_value, int base, - bool *success_ptr) { - if (s && s[0]) { - char *end = nullptr; - int64_t uval = ::strtoll(s, &end, base); - if (*end == '\0') { - if (success_ptr) - *success_ptr = true; - return uval; // All characters were used, return the result - } - } - if (success_ptr) - *success_ptr = false; - return fail_value; -} - -uint64_t ToUInt64(const char *s, uint64_t fail_value, int base, - bool *success_ptr) { - if (s && s[0]) { - char *end = nullptr; - uint64_t uval = ::strtoull(s, &end, base); - if (*end == '\0') { - if (success_ptr) - *success_ptr = true; - return uval; // All characters were used, return the result - } - } - if (success_ptr) - *success_ptr = false; - return fail_value; -} - -double ToDouble(const char *s, double fail_value, bool *success_ptr) { - if (s && s[0]) { - char *end = nullptr; - double val = strtod(s, &end); - if (*end == '\0') { - if (success_ptr) - *success_ptr = true; - return val; // All characters were used, return the result - } - } - if (success_ptr) - *success_ptr = false; - return fail_value; -} -} -} diff --git a/contrib/llvm-project/lldb/source/Host/common/TCPSocket.cpp b/contrib/llvm-project/lldb/source/Host/common/TCPSocket.cpp index ea7377edbd45..28c3fa1188c2 100644 --- a/contrib/llvm-project/lldb/source/Host/common/TCPSocket.cpp +++ b/contrib/llvm-project/lldb/source/Host/common/TCPSocket.cpp @@ -53,9 +53,7 @@ static Status GetLastSocketError() { return EC; } -namespace { -const int kType = SOCK_STREAM; -} +static const int kType = SOCK_STREAM; TCPSocket::TCPSocket(bool should_close, bool child_processes_inherit) : Socket(ProtocolTcp, should_close, child_processes_inherit) {} @@ -154,23 +152,23 @@ Status TCPSocket::Connect(llvm::StringRef name) { LLDB_LOGF(log, "TCPSocket::%s (host/port = %s)", __FUNCTION__, name.data()); Status error; - std::string host_str; - std::string port_str; - int32_t port = INT32_MIN; - if (!DecodeHostAndPort(name, host_str, port_str, port, &error)) - return error; + llvm::Expected<HostAndPort> host_port = DecodeHostAndPort(name); + if (!host_port) + return Status(host_port.takeError()); - std::vector<SocketAddress> addresses = SocketAddress::GetAddressInfo( - host_str.c_str(), nullptr, AF_UNSPEC, SOCK_STREAM, IPPROTO_TCP); + std::vector<SocketAddress> addresses = + SocketAddress::GetAddressInfo(host_port->hostname.c_str(), nullptr, + AF_UNSPEC, SOCK_STREAM, IPPROTO_TCP); for (SocketAddress &address : addresses) { error = CreateSocket(address.GetFamily()); if (error.Fail()) continue; - address.SetPort(port); + address.SetPort(host_port->port); - if (-1 == llvm::sys::RetryAfterSignal(-1, ::connect, - GetNativeSocket(), &address.sockaddr(), address.GetLength())) { + if (-1 == llvm::sys::RetryAfterSignal(-1, ::connect, GetNativeSocket(), + &address.sockaddr(), + address.GetLength())) { CLOSE_SOCKET(GetNativeSocket()); continue; } @@ -190,16 +188,14 @@ Status TCPSocket::Listen(llvm::StringRef name, int backlog) { LLDB_LOGF(log, "TCPSocket::%s (%s)", __FUNCTION__, name.data()); Status error; - std::string host_str; - std::string port_str; - int32_t port = INT32_MIN; - if (!DecodeHostAndPort(name, host_str, port_str, port, &error)) - return error; + llvm::Expected<HostAndPort> host_port = DecodeHostAndPort(name); + if (!host_port) + return Status(host_port.takeError()); - if (host_str == "*") - host_str = "0.0.0.0"; + if (host_port->hostname == "*") + host_port->hostname = "0.0.0.0"; std::vector<SocketAddress> addresses = SocketAddress::GetAddressInfo( - host_str.c_str(), nullptr, AF_UNSPEC, SOCK_STREAM, IPPROTO_TCP); + host_port->hostname.c_str(), nullptr, AF_UNSPEC, SOCK_STREAM, IPPROTO_TCP); for (SocketAddress &address : addresses) { int fd = Socket::CreateSocket(address.GetFamily(), kType, IPPROTO_TCP, m_child_processes_inherit, error); @@ -215,9 +211,9 @@ Status TCPSocket::Listen(llvm::StringRef name, int backlog) { SocketAddress listen_address = address; if(!listen_address.IsLocalhost()) - listen_address.SetToAnyAddress(address.GetFamily(), port); + listen_address.SetToAnyAddress(address.GetFamily(), host_port->port); else - listen_address.SetPort(port); + listen_address.SetPort(host_port->port); int err = ::bind(fd, &listen_address.sockaddr(), listen_address.GetLength()); @@ -230,10 +226,10 @@ Status TCPSocket::Listen(llvm::StringRef name, int backlog) { continue; } - if (port == 0) { + if (host_port->port == 0) { socklen_t sa_len = address.GetLength(); if (getsockname(fd, &address.sockaddr(), &sa_len) == 0) - port = address.GetPort(); + host_port->port = address.GetPort(); } m_listen_sockets[fd] = address; } diff --git a/contrib/llvm-project/lldb/source/Host/common/Terminal.cpp b/contrib/llvm-project/lldb/source/Host/common/Terminal.cpp index 2301abe9afb1..2a1c12e667bc 100644 --- a/contrib/llvm-project/lldb/source/Host/common/Terminal.cpp +++ b/contrib/llvm-project/lldb/source/Host/common/Terminal.cpp @@ -21,123 +21,417 @@ using namespace lldb_private; +struct Terminal::Data { +#if LLDB_ENABLE_TERMIOS + struct termios m_termios; ///< Cached terminal state information. +#endif +}; + bool Terminal::IsATerminal() const { return m_fd >= 0 && ::isatty(m_fd); } -bool Terminal::SetEcho(bool enabled) { - if (FileDescriptorIsValid()) { +#if !LLDB_ENABLE_TERMIOS +static llvm::Error termiosMissingError() { + return llvm::createStringError(llvm::inconvertibleErrorCode(), + "termios support missing in LLDB"); +} +#endif + +llvm::Expected<Terminal::Data> Terminal::GetData() { #if LLDB_ENABLE_TERMIOS - if (IsATerminal()) { - struct termios fd_termios; - if (::tcgetattr(m_fd, &fd_termios) == 0) { - bool set_corectly = false; - if (enabled) { - if (fd_termios.c_lflag & ECHO) - set_corectly = true; - else - fd_termios.c_lflag |= ECHO; - } else { - if (fd_termios.c_lflag & ECHO) - fd_termios.c_lflag &= ~ECHO; - else - set_corectly = true; - } - - if (set_corectly) - return true; - return ::tcsetattr(m_fd, TCSANOW, &fd_termios) == 0; - } - } -#endif // #if LLDB_ENABLE_TERMIOS + if (!FileDescriptorIsValid()) + return llvm::createStringError(llvm::inconvertibleErrorCode(), + "invalid fd"); + + if (!IsATerminal()) + return llvm::createStringError(llvm::inconvertibleErrorCode(), + "fd not a terminal"); + + Data data; + if (::tcgetattr(m_fd, &data.m_termios) != 0) + return llvm::createStringError( + std::error_code(errno, std::generic_category()), + "unable to get teletype attributes"); + return data; +#else // !LLDB_ENABLE_TERMIOS + return termiosMissingError(); +#endif // LLDB_ENABLE_TERMIOS +} + +llvm::Error Terminal::SetData(const Terminal::Data &data) { +#if LLDB_ENABLE_TERMIOS + assert(FileDescriptorIsValid()); + assert(IsATerminal()); + + if (::tcsetattr(m_fd, TCSANOW, &data.m_termios) != 0) + return llvm::createStringError( + std::error_code(errno, std::generic_category()), + "unable to set teletype attributes"); + return llvm::Error::success(); +#else // !LLDB_ENABLE_TERMIOS + return termiosMissingError(); +#endif // LLDB_ENABLE_TERMIOS +} + +llvm::Error Terminal::SetEcho(bool enabled) { +#if LLDB_ENABLE_TERMIOS + llvm::Expected<Data> data = GetData(); + if (!data) + return data.takeError(); + + struct termios &fd_termios = data->m_termios; + fd_termios.c_lflag &= ~ECHO; + if (enabled) + fd_termios.c_lflag |= ECHO; + return SetData(data.get()); +#else // !LLDB_ENABLE_TERMIOS + return termiosMissingError(); +#endif // LLDB_ENABLE_TERMIOS +} + +llvm::Error Terminal::SetCanonical(bool enabled) { +#if LLDB_ENABLE_TERMIOS + llvm::Expected<Data> data = GetData(); + if (!data) + return data.takeError(); + + struct termios &fd_termios = data->m_termios; + fd_termios.c_lflag &= ~ICANON; + if (enabled) + fd_termios.c_lflag |= ICANON; + return SetData(data.get()); +#else // !LLDB_ENABLE_TERMIOS + return termiosMissingError(); +#endif // LLDB_ENABLE_TERMIOS +} + +llvm::Error Terminal::SetRaw() { +#if LLDB_ENABLE_TERMIOS + llvm::Expected<Data> data = GetData(); + if (!data) + return data.takeError(); + + struct termios &fd_termios = data->m_termios; + ::cfmakeraw(&fd_termios); + + // Make sure only one character is needed to return from a read + // (cfmakeraw() doesn't do this on NetBSD) + fd_termios.c_cc[VMIN] = 1; + fd_termios.c_cc[VTIME] = 0; + + return SetData(data.get()); +#else // !LLDB_ENABLE_TERMIOS + return termiosMissingError(); +#endif // LLDB_ENABLE_TERMIOS +} + +#if LLDB_ENABLE_TERMIOS +static llvm::Optional<speed_t> baudRateToConst(unsigned int baud_rate) { + switch (baud_rate) { +#if defined(B50) + case 50: + return B50; +#endif +#if defined(B75) + case 75: + return B75; +#endif +#if defined(B110) + case 110: + return B110; +#endif +#if defined(B134) + case 134: + return B134; +#endif +#if defined(B150) + case 150: + return B150; +#endif +#if defined(B200) + case 200: + return B200; +#endif +#if defined(B300) + case 300: + return B300; +#endif +#if defined(B600) + case 600: + return B600; +#endif +#if defined(B1200) + case 1200: + return B1200; +#endif +#if defined(B1800) + case 1800: + return B1800; +#endif +#if defined(B2400) + case 2400: + return B2400; +#endif +#if defined(B4800) + case 4800: + return B4800; +#endif +#if defined(B9600) + case 9600: + return B9600; +#endif +#if defined(B19200) + case 19200: + return B19200; +#endif +#if defined(B38400) + case 38400: + return B38400; +#endif +#if defined(B57600) + case 57600: + return B57600; +#endif +#if defined(B115200) + case 115200: + return B115200; +#endif +#if defined(B230400) + case 230400: + return B230400; +#endif +#if defined(B460800) + case 460800: + return B460800; +#endif +#if defined(B500000) + case 500000: + return B500000; +#endif +#if defined(B576000) + case 576000: + return B576000; +#endif +#if defined(B921600) + case 921600: + return B921600; +#endif +#if defined(B1000000) + case 1000000: + return B1000000; +#endif +#if defined(B1152000) + case 1152000: + return B1152000; +#endif +#if defined(B1500000) + case 1500000: + return B1500000; +#endif +#if defined(B2000000) + case 2000000: + return B2000000; +#endif +#if defined(B76800) + case 76800: + return B76800; +#endif +#if defined(B153600) + case 153600: + return B153600; +#endif +#if defined(B307200) + case 307200: + return B307200; +#endif +#if defined(B614400) + case 614400: + return B614400; +#endif +#if defined(B2500000) + case 2500000: + return B2500000; +#endif +#if defined(B3000000) + case 3000000: + return B3000000; +#endif +#if defined(B3500000) + case 3500000: + return B3500000; +#endif +#if defined(B4000000) + case 4000000: + return B4000000; +#endif + default: + return llvm::None; } - return false; } +#endif -bool Terminal::SetCanonical(bool enabled) { - if (FileDescriptorIsValid()) { +llvm::Error Terminal::SetBaudRate(unsigned int baud_rate) { #if LLDB_ENABLE_TERMIOS - if (IsATerminal()) { - struct termios fd_termios; - if (::tcgetattr(m_fd, &fd_termios) == 0) { - bool set_corectly = false; - if (enabled) { - if (fd_termios.c_lflag & ICANON) - set_corectly = true; - else - fd_termios.c_lflag |= ICANON; - } else { - if (fd_termios.c_lflag & ICANON) - fd_termios.c_lflag &= ~ICANON; - else - set_corectly = true; - } - - if (set_corectly) - return true; - return ::tcsetattr(m_fd, TCSANOW, &fd_termios) == 0; - } - } -#endif // #if LLDB_ENABLE_TERMIOS + llvm::Expected<Data> data = GetData(); + if (!data) + return data.takeError(); + + struct termios &fd_termios = data->m_termios; + llvm::Optional<speed_t> val = baudRateToConst(baud_rate); + if (!val) // invalid value + return llvm::createStringError(llvm::inconvertibleErrorCode(), + "baud rate %d unsupported by the platform", + baud_rate); + if (::cfsetispeed(&fd_termios, val.getValue()) != 0) + return llvm::createStringError( + std::error_code(errno, std::generic_category()), + "setting input baud rate failed"); + if (::cfsetospeed(&fd_termios, val.getValue()) != 0) + return llvm::createStringError( + std::error_code(errno, std::generic_category()), + "setting output baud rate failed"); + return SetData(data.get()); +#else // !LLDB_ENABLE_TERMIOS + return termiosMissingError(); +#endif // LLDB_ENABLE_TERMIOS +} + +llvm::Error Terminal::SetStopBits(unsigned int stop_bits) { +#if LLDB_ENABLE_TERMIOS + llvm::Expected<Data> data = GetData(); + if (!data) + return data.takeError(); + + struct termios &fd_termios = data->m_termios; + switch (stop_bits) { + case 1: + fd_termios.c_cflag &= ~CSTOPB; + break; + case 2: + fd_termios.c_cflag |= CSTOPB; + break; + default: + return llvm::createStringError( + llvm::inconvertibleErrorCode(), + "invalid stop bit count: %d (must be 1 or 2)", stop_bits); } - return false; + return SetData(data.get()); +#else // !LLDB_ENABLE_TERMIOS + return termiosMissingError(); +#endif // LLDB_ENABLE_TERMIOS } -// Default constructor -TerminalState::TerminalState() - : m_tty() +llvm::Error Terminal::SetParity(Terminal::Parity parity) { #if LLDB_ENABLE_TERMIOS - , - m_termios_up() + llvm::Expected<Data> data = GetData(); + if (!data) + return data.takeError(); + + struct termios &fd_termios = data->m_termios; + fd_termios.c_cflag &= ~( +#if defined(CMSPAR) + CMSPAR | +#endif + PARENB | PARODD); + + if (parity != Parity::No) { + fd_termios.c_cflag |= PARENB; + if (parity == Parity::Odd || parity == Parity::Mark) + fd_termios.c_cflag |= PARODD; + if (parity == Parity::Mark || parity == Parity::Space) { +#if defined(CMSPAR) + fd_termios.c_cflag |= CMSPAR; +#else + return llvm::createStringError( + llvm::inconvertibleErrorCode(), + "space/mark parity is not supported by the platform"); #endif -{ + } + } + return SetData(data.get()); +#else // !LLDB_ENABLE_TERMIOS + return termiosMissingError(); +#endif // LLDB_ENABLE_TERMIOS +} + +llvm::Error Terminal::SetParityCheck(Terminal::ParityCheck parity_check) { +#if LLDB_ENABLE_TERMIOS + llvm::Expected<Data> data = GetData(); + if (!data) + return data.takeError(); + + struct termios &fd_termios = data->m_termios; + fd_termios.c_iflag &= ~(IGNPAR | PARMRK | INPCK); + + if (parity_check != ParityCheck::No) { + fd_termios.c_iflag |= INPCK; + if (parity_check == ParityCheck::Ignore) + fd_termios.c_iflag |= IGNPAR; + else if (parity_check == ParityCheck::Mark) + fd_termios.c_iflag |= PARMRK; + } + return SetData(data.get()); +#else // !LLDB_ENABLE_TERMIOS + return termiosMissingError(); +#endif // LLDB_ENABLE_TERMIOS +} + +llvm::Error Terminal::SetHardwareFlowControl(bool enabled) { +#if LLDB_ENABLE_TERMIOS + llvm::Expected<Data> data = GetData(); + if (!data) + return data.takeError(); + +#if defined(CRTSCTS) + struct termios &fd_termios = data->m_termios; + fd_termios.c_cflag &= ~CRTSCTS; + if (enabled) + fd_termios.c_cflag |= CRTSCTS; + return SetData(data.get()); +#else // !defined(CRTSCTS) + if (enabled) + return llvm::createStringError( + llvm::inconvertibleErrorCode(), + "hardware flow control is not supported by the platform"); + return llvm::Error::success(); +#endif // defined(CRTSCTS) +#else // !LLDB_ENABLE_TERMIOS + return termiosMissingError(); +#endif // LLDB_ENABLE_TERMIOS +} + +TerminalState::TerminalState(Terminal term, bool save_process_group) + : m_tty(term) { + Save(term, save_process_group); } -// Destructor -TerminalState::~TerminalState() = default; +TerminalState::~TerminalState() { Restore(); } void TerminalState::Clear() { m_tty.Clear(); m_tflags = -1; -#if LLDB_ENABLE_TERMIOS - m_termios_up.reset(); -#endif + m_data.reset(); m_process_group = -1; } -// Save the current state of the TTY for the file descriptor "fd" and if -// "save_process_group" is true, attempt to save the process group info for the -// TTY. -bool TerminalState::Save(int fd, bool save_process_group) { - m_tty.SetFileDescriptor(fd); +bool TerminalState::Save(Terminal term, bool save_process_group) { + Clear(); + m_tty = term; if (m_tty.IsATerminal()) { + int fd = m_tty.GetFileDescriptor(); #if LLDB_ENABLE_POSIX m_tflags = ::fcntl(fd, F_GETFL, 0); -#endif #if LLDB_ENABLE_TERMIOS - if (m_termios_up == nullptr) - m_termios_up.reset(new struct termios); - int err = ::tcgetattr(fd, m_termios_up.get()); - if (err != 0) - m_termios_up.reset(); -#endif // #if LLDB_ENABLE_TERMIOS -#if LLDB_ENABLE_POSIX + std::unique_ptr<Terminal::Data> new_data{new Terminal::Data()}; + if (::tcgetattr(fd, &new_data->m_termios) == 0) + m_data = std::move(new_data); +#endif // LLDB_ENABLE_TERMIOS if (save_process_group) - m_process_group = ::tcgetpgrp(0); - else - m_process_group = -1; -#endif - } else { - m_tty.Clear(); - m_tflags = -1; -#if LLDB_ENABLE_TERMIOS - m_termios_up.reset(); -#endif - m_process_group = -1; + m_process_group = ::tcgetpgrp(fd); +#endif // LLDB_ENABLE_POSIX } return IsValid(); } -// Restore the state of the TTY using the cached values from a previous call to -// Save(). bool TerminalState::Restore() const { #if LLDB_ENABLE_POSIX if (IsValid()) { @@ -147,8 +441,8 @@ bool TerminalState::Restore() const { #if LLDB_ENABLE_TERMIOS if (TTYStateIsValid()) - tcsetattr(fd, TCSANOW, m_termios_up.get()); -#endif // #if LLDB_ENABLE_TERMIOS + tcsetattr(fd, TCSANOW, &m_data->m_termios); +#endif // LLDB_ENABLE_TERMIOS if (ProcessGroupIsValid()) { // Save the original signal handler. @@ -161,77 +455,19 @@ bool TerminalState::Restore() const { } return true; } -#endif +#endif // LLDB_ENABLE_POSIX return false; } -// Returns true if this object has valid saved TTY state settings that can be -// used to restore a previous state. bool TerminalState::IsValid() const { return m_tty.FileDescriptorIsValid() && - (TFlagsIsValid() || TTYStateIsValid()); + (TFlagsIsValid() || TTYStateIsValid() || ProcessGroupIsValid()); } -// Returns true if m_tflags is valid bool TerminalState::TFlagsIsValid() const { return m_tflags != -1; } -// Returns true if m_ttystate is valid -bool TerminalState::TTYStateIsValid() const { -#if LLDB_ENABLE_TERMIOS - return m_termios_up != nullptr; -#else - return false; -#endif -} +bool TerminalState::TTYStateIsValid() const { return bool(m_data); } -// Returns true if m_process_group is valid bool TerminalState::ProcessGroupIsValid() const { return static_cast<int32_t>(m_process_group) != -1; } - -// Constructor -TerminalStateSwitcher::TerminalStateSwitcher() = default; - -// Destructor -TerminalStateSwitcher::~TerminalStateSwitcher() = default; - -// Returns the number of states that this switcher contains -uint32_t TerminalStateSwitcher::GetNumberOfStates() const { - return llvm::array_lengthof(m_ttystates); -} - -// Restore the state at index "idx". -// -// Returns true if the restore was successful, false otherwise. -bool TerminalStateSwitcher::Restore(uint32_t idx) const { - const uint32_t num_states = GetNumberOfStates(); - if (idx >= num_states) - return false; - - // See if we already are in this state? - if (m_currentState < num_states && (idx == m_currentState) && - m_ttystates[idx].IsValid()) - return true; - - // Set the state to match the index passed in and only update the current - // state if there are no errors. - if (m_ttystates[idx].Restore()) { - m_currentState = idx; - return true; - } - - // We failed to set the state. The tty state was invalid or not initialized. - return false; -} - -// Save the state at index "idx" for file descriptor "fd" and save the process -// group if requested. -// -// Returns true if the restore was successful, false otherwise. -bool TerminalStateSwitcher::Save(uint32_t idx, int fd, - bool save_process_group) { - const uint32_t num_states = GetNumberOfStates(); - if (idx < num_states) - return m_ttystates[idx].Save(fd, save_process_group); - return false; -} diff --git a/contrib/llvm-project/lldb/source/Host/common/UDPSocket.cpp b/contrib/llvm-project/lldb/source/Host/common/UDPSocket.cpp index 0b537b3a9b13..31266c980e0e 100644 --- a/contrib/llvm-project/lldb/source/Host/common/UDPSocket.cpp +++ b/contrib/llvm-project/lldb/source/Host/common/UDPSocket.cpp @@ -21,13 +21,10 @@ using namespace lldb; using namespace lldb_private; -namespace { - -const int kDomain = AF_INET; -const int kType = SOCK_DGRAM; +static const int kDomain = AF_INET; +static const int kType = SOCK_DGRAM; static const char *g_not_supported_error = "Not supported"; -} UDPSocket::UDPSocket(NativeSocket socket) : Socket(ProtocolUdp, true, true) { m_socket = socket; @@ -61,11 +58,9 @@ UDPSocket::Connect(llvm::StringRef name, bool child_processes_inherit) { LLDB_LOG(log, "host/port = {0}", name); Status error; - std::string host_str; - std::string port_str; - int32_t port = INT32_MIN; - if (!DecodeHostAndPort(name, host_str, port_str, port, &error)) - return error.ToError(); + llvm::Expected<HostAndPort> host_port = DecodeHostAndPort(name); + if (!host_port) + return host_port.takeError(); // At this point we have setup the receive port, now we need to setup the UDP // send socket @@ -76,16 +71,16 @@ UDPSocket::Connect(llvm::StringRef name, bool child_processes_inherit) { ::memset(&hints, 0, sizeof(hints)); hints.ai_family = kDomain; hints.ai_socktype = kType; - int err = ::getaddrinfo(host_str.c_str(), port_str.c_str(), &hints, + int err = ::getaddrinfo(host_port->hostname.c_str(), std::to_string(host_port->port).c_str(), &hints, &service_info_list); if (err != 0) { error.SetErrorStringWithFormat( #if defined(_WIN32) && defined(UNICODE) - "getaddrinfo(%s, %s, &hints, &info) returned error %i (%S)", + "getaddrinfo(%s, %d, &hints, &info) returned error %i (%S)", #else - "getaddrinfo(%s, %s, &hints, &info) returned error %i (%s)", + "getaddrinfo(%s, %d, &hints, &info) returned error %i (%s)", #endif - host_str.c_str(), port_str.c_str(), err, gai_strerror(err)); + host_port->hostname.c_str(), host_port->port, err, gai_strerror(err)); return error.ToError(); } @@ -112,9 +107,9 @@ UDPSocket::Connect(llvm::StringRef name, bool child_processes_inherit) { // Only bind to the loopback address if we are expecting a connection from // localhost to avoid any firewall issues. - const bool bind_addr_success = (host_str == "127.0.0.1" || host_str == "localhost") - ? bind_addr.SetToLocalhost(kDomain, port) - : bind_addr.SetToAnyAddress(kDomain, port); + const bool bind_addr_success = (host_port->hostname == "127.0.0.1" || host_port->hostname == "localhost") + ? bind_addr.SetToLocalhost(kDomain, host_port->port) + : bind_addr.SetToAnyAddress(kDomain, host_port->port); if (!bind_addr_success) { error.SetErrorString("Failed to get hostspec to bind for"); diff --git a/contrib/llvm-project/lldb/source/Host/common/XML.cpp b/contrib/llvm-project/lldb/source/Host/common/XML.cpp index c3225d3f4433..79128b98dc38 100644 --- a/contrib/llvm-project/lldb/source/Host/common/XML.cpp +++ b/contrib/llvm-project/lldb/source/Host/common/XML.cpp @@ -6,10 +6,7 @@ // //===----------------------------------------------------------------------===// -#include <stdlib.h> /* atof */ - #include "lldb/Host/Config.h" -#include "lldb/Host/StringConvert.h" #include "lldb/Host/XML.h" using namespace lldb; @@ -153,14 +150,8 @@ llvm::StringRef XMLNode::GetAttributeValue(const char *name, bool XMLNode::GetAttributeValueAsUnsigned(const char *name, uint64_t &value, uint64_t fail_value, int base) const { -#if LLDB_ENABLE_LIBXML2 - llvm::StringRef str_value = GetAttributeValue(name, ""); -#else - llvm::StringRef str_value; -#endif - bool success = false; - value = StringConvert::ToUInt64(str_value.data(), fail_value, base, &success); - return success; + value = fail_value; + return llvm::to_integer(GetAttributeValue(name, ""), value, base); } void XMLNode::ForEachChildNode(NodeCallback const &callback) const { @@ -302,33 +293,17 @@ bool XMLNode::GetElementText(std::string &text) const { bool XMLNode::GetElementTextAsUnsigned(uint64_t &value, uint64_t fail_value, int base) const { - bool success = false; -#if LLDB_ENABLE_LIBXML2 - if (IsValid()) { - std::string text; - if (GetElementText(text)) - value = StringConvert::ToUInt64(text.c_str(), fail_value, base, &success); - } -#endif - if (!success) - value = fail_value; - return success; + std::string text; + + value = fail_value; + return GetElementText(text) && llvm::to_integer(text, value, base); } bool XMLNode::GetElementTextAsFloat(double &value, double fail_value) const { - bool success = false; -#if LLDB_ENABLE_LIBXML2 - if (IsValid()) { - std::string text; - if (GetElementText(text)) { - value = atof(text.c_str()); - success = true; - } - } -#endif - if (!success) - value = fail_value; - return success; + std::string text; + + value = fail_value; + return GetElementText(text) && llvm::to_float(text, value); } bool XMLNode::NameIs(const char *name) const { @@ -473,9 +448,7 @@ bool ApplePropertyList::ExtractStringFromValueNode(const XMLNode &node, #if LLDB_ENABLE_LIBXML2 -namespace { - -StructuredData::ObjectSP CreatePlistValue(XMLNode node) { +static StructuredData::ObjectSP CreatePlistValue(XMLNode node) { llvm::StringRef element_name = node.GetName(); if (element_name == "array") { std::shared_ptr<StructuredData::Array> array_sp( @@ -528,7 +501,6 @@ StructuredData::ObjectSP CreatePlistValue(XMLNode node) { } return StructuredData::ObjectSP(new StructuredData::Null()); } -} #endif StructuredData::ObjectSP ApplePropertyList::GetStructuredData() { diff --git a/contrib/llvm-project/lldb/source/Host/freebsd/HostInfoFreeBSD.cpp b/contrib/llvm-project/lldb/source/Host/freebsd/HostInfoFreeBSD.cpp index 1b9e3ccaf181..f9ff45666c1e 100644 --- a/contrib/llvm-project/lldb/source/Host/freebsd/HostInfoFreeBSD.cpp +++ b/contrib/llvm-project/lldb/source/Host/freebsd/HostInfoFreeBSD.cpp @@ -7,7 +7,7 @@ //===----------------------------------------------------------------------===// #include "lldb/Host/freebsd/HostInfoFreeBSD.h" - +#include "llvm/Support/FormatVariadic.h" #include <cstdio> #include <cstring> #include <sys/sysctl.h> @@ -30,34 +30,15 @@ llvm::VersionTuple HostInfoFreeBSD::GetOSVersion() { return llvm::VersionTuple(); } -bool HostInfoFreeBSD::GetOSBuildString(std::string &s) { +llvm::Optional<std::string> HostInfoFreeBSD::GetOSBuildString() { int mib[2] = {CTL_KERN, KERN_OSREV}; - char osrev_str[12]; uint32_t osrev = 0; size_t osrev_len = sizeof(osrev); - if (::sysctl(mib, 2, &osrev, &osrev_len, NULL, 0) == 0) { - ::snprintf(osrev_str, sizeof(osrev_str), "%-8.8u", osrev); - s.assign(osrev_str); - return true; - } - - s.clear(); - return false; -} - -bool HostInfoFreeBSD::GetOSKernelDescription(std::string &s) { - struct utsname un; - - ::memset(&un, 0, sizeof(utsname)); - s.clear(); - - if (uname(&un) < 0) - return false; - - s.assign(un.version); + if (::sysctl(mib, 2, &osrev, &osrev_len, NULL, 0) == 0) + return llvm::formatv("{0,8:8}", osrev).str(); - return true; + return llvm::None; } FileSpec HostInfoFreeBSD::GetProgramFileSpec() { diff --git a/contrib/llvm-project/lldb/source/Host/netbsd/HostInfoNetBSD.cpp b/contrib/llvm-project/lldb/source/Host/netbsd/HostInfoNetBSD.cpp index bddd46cec3ee..234dd3d5e103 100644 --- a/contrib/llvm-project/lldb/source/Host/netbsd/HostInfoNetBSD.cpp +++ b/contrib/llvm-project/lldb/source/Host/netbsd/HostInfoNetBSD.cpp @@ -42,34 +42,16 @@ llvm::VersionTuple HostInfoNetBSD::GetOSVersion() { return llvm::VersionTuple(); } -bool HostInfoNetBSD::GetOSBuildString(std::string &s) { +llvm::Optional<std::string> HostInfoNetBSD::GetOSBuildString() { int mib[2] = {CTL_KERN, KERN_OSREV}; char osrev_str[12]; int osrev = 0; size_t osrev_len = sizeof(osrev); - if (::sysctl(mib, 2, &osrev, &osrev_len, NULL, 0) == 0) { - ::snprintf(osrev_str, sizeof(osrev_str), "%-10.10d", osrev); - s.assign(osrev_str); - return true; - } - - s.clear(); - return false; -} - -bool HostInfoNetBSD::GetOSKernelDescription(std::string &s) { - struct utsname un; - - ::memset(&un, 0, sizeof(un)); - s.clear(); - - if (::uname(&un) < 0) - return false; - - s.assign(un.version); + if (::sysctl(mib, 2, &osrev, &osrev_len, NULL, 0) == 0) + return llvm::formatv("{0,10:10}", osrev).str(); - return true; + return llvm::None; } FileSpec HostInfoNetBSD::GetProgramFileSpec() { diff --git a/contrib/llvm-project/lldb/source/Host/openbsd/HostInfoOpenBSD.cpp b/contrib/llvm-project/lldb/source/Host/openbsd/HostInfoOpenBSD.cpp index 9617375babe1..5db843ff628d 100644 --- a/contrib/llvm-project/lldb/source/Host/openbsd/HostInfoOpenBSD.cpp +++ b/contrib/llvm-project/lldb/source/Host/openbsd/HostInfoOpenBSD.cpp @@ -29,34 +29,16 @@ llvm::VersionTuple HostInfoOpenBSD::GetOSVersion() { return llvm::VersionTuple(); } -bool HostInfoOpenBSD::GetOSBuildString(std::string &s) { +llvm::Optional<std::string> HostInfoOpenBSD::GetOSBuildString() { int mib[2] = {CTL_KERN, KERN_OSREV}; char osrev_str[12]; uint32_t osrev = 0; size_t osrev_len = sizeof(osrev); - if (::sysctl(mib, 2, &osrev, &osrev_len, NULL, 0) == 0) { - ::snprintf(osrev_str, sizeof(osrev_str), "%-8.8u", osrev); - s.assign(osrev_str); - return true; - } + if (::sysctl(mib, 2, &osrev, &osrev_len, NULL, 0) == 0) + return llvm::formatv("{0,8:8}", osrev).str(); - s.clear(); - return false; -} - -bool HostInfoOpenBSD::GetOSKernelDescription(std::string &s) { - struct utsname un; - - ::memset(&un, 0, sizeof(utsname)); - s.clear(); - - if (uname(&un) < 0) - return false; - - s.assign(un.version); - - return true; + return llvm::None; } FileSpec HostInfoOpenBSD::GetProgramFileSpec() { diff --git a/contrib/llvm-project/lldb/source/Host/posix/ConnectionFileDescriptorPosix.cpp b/contrib/llvm-project/lldb/source/Host/posix/ConnectionFileDescriptorPosix.cpp index 2f4cc960f02d..b3140f7b0fd7 100644 --- a/contrib/llvm-project/lldb/source/Host/posix/ConnectionFileDescriptorPosix.cpp +++ b/contrib/llvm-project/lldb/source/Host/posix/ConnectionFileDescriptorPosix.cpp @@ -13,10 +13,10 @@ #define _DARWIN_UNLIMITED_SELECT #endif -#include "lldb/Host/posix/ConnectionFileDescriptorPosix.h" #include "lldb/Host/Config.h" #include "lldb/Host/Socket.h" #include "lldb/Host/SocketAddress.h" +#include "lldb/Host/posix/ConnectionFileDescriptorPosix.h" #include "lldb/Utility/SelectHelper.h" #include "lldb/Utility/Timeout.h" @@ -50,30 +50,6 @@ using namespace lldb; using namespace lldb_private; -const char *ConnectionFileDescriptor::LISTEN_SCHEME = "listen"; -const char *ConnectionFileDescriptor::ACCEPT_SCHEME = "accept"; -const char *ConnectionFileDescriptor::UNIX_ACCEPT_SCHEME = "unix-accept"; -const char *ConnectionFileDescriptor::CONNECT_SCHEME = "connect"; -const char *ConnectionFileDescriptor::TCP_CONNECT_SCHEME = "tcp-connect"; -const char *ConnectionFileDescriptor::UDP_SCHEME = "udp"; -const char *ConnectionFileDescriptor::UNIX_CONNECT_SCHEME = "unix-connect"; -const char *ConnectionFileDescriptor::UNIX_ABSTRACT_CONNECT_SCHEME = - "unix-abstract-connect"; -const char *ConnectionFileDescriptor::FD_SCHEME = "fd"; -const char *ConnectionFileDescriptor::FILE_SCHEME = "file"; - -namespace { - -llvm::Optional<llvm::StringRef> GetURLAddress(llvm::StringRef url, - llvm::StringRef scheme) { - if (!url.consume_front(scheme)) - return llvm::None; - if (!url.consume_front("://")) - return llvm::None; - return url; -} -} - ConnectionFileDescriptor::ConnectionFileDescriptor(bool child_processes_inherit) : Connection(), m_pipe(), m_mutex(), m_shutting_down(false), @@ -86,9 +62,9 @@ ConnectionFileDescriptor::ConnectionFileDescriptor(bool child_processes_inherit) ConnectionFileDescriptor::ConnectionFileDescriptor(int fd, bool owns_fd) : Connection(), m_pipe(), m_mutex(), m_shutting_down(false), - m_waiting_for_accept(false), m_child_processes_inherit(false) { - m_write_sp = std::make_shared<NativeFile>(fd, File::eOpenOptionWrite, owns_fd); - m_read_sp = std::make_shared<NativeFile>(fd, File::eOpenOptionRead, false); + m_child_processes_inherit(false) { + m_io_sp = + std::make_shared<NativeFile>(fd, File::eOpenOptionReadWrite, owns_fd); Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_CONNECTION | LIBLLDB_LOG_OBJECT)); @@ -101,7 +77,7 @@ ConnectionFileDescriptor::ConnectionFileDescriptor(int fd, bool owns_fd) ConnectionFileDescriptor::ConnectionFileDescriptor(Socket *socket) : Connection(), m_pipe(), m_mutex(), m_shutting_down(false), - m_waiting_for_accept(false), m_child_processes_inherit(false) { + m_child_processes_inherit(false) { InitializeSocket(socket); } @@ -143,12 +119,18 @@ void ConnectionFileDescriptor::CloseCommandPipe() { } bool ConnectionFileDescriptor::IsConnected() const { - return (m_read_sp && m_read_sp->IsValid()) || - (m_write_sp && m_write_sp->IsValid()); + return m_io_sp && m_io_sp->IsValid(); } ConnectionStatus ConnectionFileDescriptor::Connect(llvm::StringRef path, Status *error_ptr) { + return Connect(path, nullptr, error_ptr); +} + +ConnectionStatus +ConnectionFileDescriptor::Connect(llvm::StringRef path, + socket_id_callback_type socket_id_callback, + Status *error_ptr) { std::lock_guard<std::recursive_mutex> guard(m_mutex); Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_CONNECTION)); LLDB_LOGF(log, "%p ConnectionFileDescriptor::Connect (url = '%s')", @@ -156,133 +138,47 @@ ConnectionStatus ConnectionFileDescriptor::Connect(llvm::StringRef path, OpenCommandPipe(); + if (path.empty()) { + if (error_ptr) + error_ptr->SetErrorString("invalid connect arguments"); + return eConnectionStatusError; + } + + llvm::StringRef scheme; + std::tie(scheme, path) = path.split("://"); + if (!path.empty()) { - llvm::Optional<llvm::StringRef> addr; - if ((addr = GetURLAddress(path, LISTEN_SCHEME))) { - // listen://HOST:PORT - return SocketListenAndAccept(*addr, error_ptr); - } else if ((addr = GetURLAddress(path, ACCEPT_SCHEME))) { - // unix://SOCKNAME - return NamedSocketAccept(*addr, error_ptr); - } else if ((addr = GetURLAddress(path, UNIX_ACCEPT_SCHEME))) { - // unix://SOCKNAME - return NamedSocketAccept(*addr, error_ptr); - } else if ((addr = GetURLAddress(path, CONNECT_SCHEME))) { - return ConnectTCP(*addr, error_ptr); - } else if ((addr = GetURLAddress(path, TCP_CONNECT_SCHEME))) { - return ConnectTCP(*addr, error_ptr); - } else if ((addr = GetURLAddress(path, UDP_SCHEME))) { - return ConnectUDP(*addr, error_ptr); - } else if ((addr = GetURLAddress(path, UNIX_CONNECT_SCHEME))) { - // unix-connect://SOCKNAME - return NamedSocketConnect(*addr, error_ptr); - } else if ((addr = GetURLAddress(path, UNIX_ABSTRACT_CONNECT_SCHEME))) { - // unix-abstract-connect://SOCKNAME - return UnixAbstractSocketConnect(*addr, error_ptr); - } + auto method = + llvm::StringSwitch<ConnectionStatus (ConnectionFileDescriptor::*)( + llvm::StringRef, socket_id_callback_type, Status *)>(scheme) + .Case("listen", &ConnectionFileDescriptor::AcceptTCP) + .Cases("accept", "unix-accept", + &ConnectionFileDescriptor::AcceptNamedSocket) + .Case("unix-abstract-accept", + &ConnectionFileDescriptor::AcceptAbstractSocket) + .Cases("connect", "tcp-connect", + &ConnectionFileDescriptor::ConnectTCP) + .Case("udp", &ConnectionFileDescriptor::ConnectUDP) + .Case("unix-connect", &ConnectionFileDescriptor::ConnectNamedSocket) + .Case("unix-abstract-connect", + &ConnectionFileDescriptor::ConnectAbstractSocket) #if LLDB_ENABLE_POSIX - else if ((addr = GetURLAddress(path, FD_SCHEME))) { - // Just passing a native file descriptor within this current process that - // is already opened (possibly from a service or other source). - int fd = -1; - - if (!addr->getAsInteger(0, fd)) { - // We have what looks to be a valid file descriptor, but we should make - // sure it is. We currently are doing this by trying to get the flags - // from the file descriptor and making sure it isn't a bad fd. - errno = 0; - int flags = ::fcntl(fd, F_GETFL, 0); - if (flags == -1 || errno == EBADF) { - if (error_ptr) - error_ptr->SetErrorStringWithFormat("stale file descriptor: %s", - path.str().c_str()); - m_read_sp.reset(); - m_write_sp.reset(); - return eConnectionStatusError; - } else { - // Don't take ownership of a file descriptor that gets passed to us - // since someone else opened the file descriptor and handed it to us. - // TODO: Since are using a URL to open connection we should - // eventually parse options using the web standard where we have - // "fd://123?opt1=value;opt2=value" and we can have an option be - // "owns=1" or "owns=0" or something like this to allow us to specify - // this. For now, we assume we must assume we don't own it. - - std::unique_ptr<TCPSocket> tcp_socket; - tcp_socket = std::make_unique<TCPSocket>(fd, false, false); - // Try and get a socket option from this file descriptor to see if - // this is a socket and set m_is_socket accordingly. - int resuse; - bool is_socket = - !!tcp_socket->GetOption(SOL_SOCKET, SO_REUSEADDR, resuse); - if (is_socket) { - m_read_sp = std::move(tcp_socket); - m_write_sp = m_read_sp; - } else { - m_read_sp = - std::make_shared<NativeFile>(fd, File::eOpenOptionRead, false); - m_write_sp = - std::make_shared<NativeFile>(fd, File::eOpenOptionWrite, false); - } - m_uri = std::string(*addr); - return eConnectionStatusSuccess; - } - } + .Case("fd", &ConnectionFileDescriptor::ConnectFD) + .Case("file", &ConnectionFileDescriptor::ConnectFile) + .Case("serial", &ConnectionFileDescriptor::ConnectSerialPort) +#endif + .Default(nullptr); + if (method) { if (error_ptr) - error_ptr->SetErrorStringWithFormat("invalid file descriptor: \"%s\"", - path.str().c_str()); - m_read_sp.reset(); - m_write_sp.reset(); - return eConnectionStatusError; - } else if ((addr = GetURLAddress(path, FILE_SCHEME))) { - std::string addr_str = addr->str(); - // file:///PATH - int fd = llvm::sys::RetryAfterSignal(-1, ::open, addr_str.c_str(), O_RDWR); - if (fd == -1) { - if (error_ptr) - error_ptr->SetErrorToErrno(); - return eConnectionStatusError; - } - - if (::isatty(fd)) { - // Set up serial terminal emulation - struct termios options; - ::tcgetattr(fd, &options); - - // Set port speed to maximum - ::cfsetospeed(&options, B115200); - ::cfsetispeed(&options, B115200); - - // Raw input, disable echo and signals - options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); - - // Make sure only one character is needed to return from a read - options.c_cc[VMIN] = 1; - options.c_cc[VTIME] = 0; - - llvm::sys::RetryAfterSignal(-1, ::tcsetattr, fd, TCSANOW, &options); - } - - int flags = ::fcntl(fd, F_GETFL, 0); - if (flags >= 0) { - if ((flags & O_NONBLOCK) == 0) { - flags |= O_NONBLOCK; - ::fcntl(fd, F_SETFL, flags); - } - } - m_read_sp = std::make_shared<NativeFile>(fd, File::eOpenOptionRead, true); - m_write_sp = std::make_shared<NativeFile>(fd, File::eOpenOptionWrite, false); - return eConnectionStatusSuccess; + *error_ptr = Status(); + return (this->*method)(path, socket_id_callback, error_ptr); } -#endif - if (error_ptr) - error_ptr->SetErrorStringWithFormat("unsupported connection URL: '%s'", - path.str().c_str()); - return eConnectionStatusError; } + if (error_ptr) - error_ptr->SetErrorString("invalid connect arguments"); + error_ptr->SetErrorStringWithFormat("unsupported connection URL: '%s'", + path.str().c_str()); return eConnectionStatusError; } @@ -306,9 +202,8 @@ ConnectionStatus ConnectionFileDescriptor::Disconnect(Status *error_ptr) { return eConnectionStatusSuccess; } - if (m_read_sp && m_read_sp->IsValid() && - m_read_sp->GetFdType() == IOObject::eFDTypeSocket) - static_cast<Socket &>(*m_read_sp).PreDisconnect(); + if (m_io_sp->GetFdType() == IOObject::eFDTypeSocket) + static_cast<Socket &>(*m_io_sp).PreDisconnect(); // Try to get the ConnectionFileDescriptor's mutex. If we fail, that is // quite likely because somebody is doing a blocking read on our file @@ -337,12 +232,11 @@ ConnectionStatus ConnectionFileDescriptor::Disconnect(Status *error_ptr) { // Prevents reads and writes during shutdown. m_shutting_down = true; - Status error = m_read_sp->Close(); - Status error2 = m_write_sp->Close(); - if (error.Fail() || error2.Fail()) + Status error = m_io_sp->Close(); + if (error.Fail()) status = eConnectionStatusError; if (error_ptr) - *error_ptr = error.Fail() ? error : error2; + *error_ptr = error; // Close any pipes we were using for async interrupts m_pipe.Close(); @@ -384,14 +278,14 @@ size_t ConnectionFileDescriptor::Read(void *dst, size_t dst_len, Status error; size_t bytes_read = dst_len; - error = m_read_sp->Read(dst, bytes_read); + error = m_io_sp->Read(dst, bytes_read); if (log) { LLDB_LOGF(log, "%p ConnectionFileDescriptor::Read() fd = %" PRIu64 ", dst = %p, dst_len = %" PRIu64 ") => %" PRIu64 ", error = %s", static_cast<void *>(this), - static_cast<uint64_t>(m_read_sp->GetWaitableHandle()), + static_cast<uint64_t>(m_io_sp->GetWaitableHandle()), static_cast<void *>(dst), static_cast<uint64_t>(dst_len), static_cast<uint64_t>(bytes_read), error.AsCString()); } @@ -410,7 +304,7 @@ size_t ConnectionFileDescriptor::Read(void *dst, size_t dst_len, switch (error_value) { case EAGAIN: // The file was marked for non-blocking I/O, and no data were // ready to be read. - if (m_read_sp->GetFdType() == IOObject::eFDTypeSocket) + if (m_io_sp->GetFdType() == IOObject::eFDTypeSocket) status = eConnectionStatusTimedOut; else status = eConnectionStatusSuccess; @@ -488,14 +382,14 @@ size_t ConnectionFileDescriptor::Write(const void *src, size_t src_len, Status error; size_t bytes_sent = src_len; - error = m_write_sp->Write(src, bytes_sent); + error = m_io_sp->Write(src, bytes_sent); if (log) { LLDB_LOGF(log, "%p ConnectionFileDescriptor::Write(fd = %" PRIu64 ", src = %p, src_len = %" PRIu64 ") => %" PRIu64 " (error = %s)", static_cast<void *>(this), - static_cast<uint64_t>(m_write_sp->GetWaitableHandle()), + static_cast<uint64_t>(m_io_sp->GetWaitableHandle()), static_cast<const void *>(src), static_cast<uint64_t>(src_len), static_cast<uint64_t>(bytes_sent), error.AsCString()); } @@ -558,7 +452,7 @@ ConnectionFileDescriptor::BytesAvailable(const Timeout<std::micro> &timeout, // Make a copy of the file descriptors to make sure we don't have another // thread change these values out from under us and cause problems in the // loop below where like in FS_SET() - const IOObject::WaitableHandle handle = m_read_sp->GetWaitableHandle(); + const IOObject::WaitableHandle handle = m_io_sp->GetWaitableHandle(); const int pipe_fd = m_pipe.GetReadFileDescriptor(); if (handle != IOObject::kInvalidHandleValue) { @@ -579,7 +473,7 @@ ConnectionFileDescriptor::BytesAvailable(const Timeout<std::micro> &timeout, if (have_pipe_fd) select_helper.FDSetRead(pipe_fd); - while (handle == m_read_sp->GetWaitableHandle()) { + while (handle == m_io_sp->GetWaitableHandle()) { Status error = select_helper.Select(); @@ -616,7 +510,8 @@ ConnectionFileDescriptor::BytesAvailable(const Timeout<std::micro> &timeout, // data from that pipe: char c; - ssize_t bytes_read = llvm::sys::RetryAfterSignal(-1, ::read, pipe_fd, &c, 1); + ssize_t bytes_read = + llvm::sys::RetryAfterSignal(-1, ::read, pipe_fd, &c, 1); assert(bytes_read == 1); (void)bytes_read; switch (c) { @@ -640,95 +535,123 @@ ConnectionFileDescriptor::BytesAvailable(const Timeout<std::micro> &timeout, return eConnectionStatusLostConnection; } -ConnectionStatus -ConnectionFileDescriptor::NamedSocketAccept(llvm::StringRef socket_name, - Status *error_ptr) { - Socket *socket = nullptr; - Status error = - Socket::UnixDomainAccept(socket_name, m_child_processes_inherit, socket); - if (error_ptr) - *error_ptr = error; - m_write_sp.reset(socket); - m_read_sp = m_write_sp; - if (error.Fail()) { - return eConnectionStatusError; +lldb::ConnectionStatus ConnectionFileDescriptor::AcceptSocket( + Socket::SocketProtocol socket_protocol, llvm::StringRef socket_name, + llvm::function_ref<void(Socket &)> post_listen_callback, + Status *error_ptr) { + Status error; + std::unique_ptr<Socket> listening_socket = + Socket::Create(socket_protocol, m_child_processes_inherit, error); + Socket *accepted_socket; + + if (!error.Fail()) + error = listening_socket->Listen(socket_name, 5); + + if (!error.Fail()) { + post_listen_callback(*listening_socket); + error = listening_socket->Accept(accepted_socket); + } + + if (!error.Fail()) { + m_io_sp.reset(accepted_socket); + m_uri.assign(socket_name.str()); + return eConnectionStatusSuccess; } - m_uri.assign(std::string(socket_name)); - return eConnectionStatusSuccess; -} -ConnectionStatus -ConnectionFileDescriptor::NamedSocketConnect(llvm::StringRef socket_name, - Status *error_ptr) { - Socket *socket = nullptr; - Status error = - Socket::UnixDomainConnect(socket_name, m_child_processes_inherit, socket); if (error_ptr) *error_ptr = error; - m_write_sp.reset(socket); - m_read_sp = m_write_sp; - if (error.Fail()) { - return eConnectionStatusError; - } - m_uri.assign(std::string(socket_name)); - return eConnectionStatusSuccess; + return eConnectionStatusError; } lldb::ConnectionStatus -ConnectionFileDescriptor::UnixAbstractSocketConnect(llvm::StringRef socket_name, - Status *error_ptr) { - Socket *socket = nullptr; - Status error = Socket::UnixAbstractConnect(socket_name, - m_child_processes_inherit, socket); +ConnectionFileDescriptor::ConnectSocket(Socket::SocketProtocol socket_protocol, + llvm::StringRef socket_name, + Status *error_ptr) { + Status error; + std::unique_ptr<Socket> socket = + Socket::Create(socket_protocol, m_child_processes_inherit, error); + + if (!error.Fail()) + error = socket->Connect(socket_name); + + if (!error.Fail()) { + m_io_sp = std::move(socket); + m_uri.assign(socket_name.str()); + return eConnectionStatusSuccess; + } + if (error_ptr) *error_ptr = error; - m_write_sp.reset(socket); - m_read_sp = m_write_sp; - if (error.Fail()) { - return eConnectionStatusError; - } - m_uri.assign(std::string(socket_name)); - return eConnectionStatusSuccess; + return eConnectionStatusError; } -ConnectionStatus -ConnectionFileDescriptor::SocketListenAndAccept(llvm::StringRef s, - Status *error_ptr) { - if (error_ptr) - *error_ptr = Status(); - m_port_predicate.SetValue(0, eBroadcastNever); +ConnectionStatus ConnectionFileDescriptor::AcceptNamedSocket( + llvm::StringRef socket_name, socket_id_callback_type socket_id_callback, + Status *error_ptr) { + return AcceptSocket( + Socket::ProtocolUnixDomain, socket_name, + [socket_id_callback, socket_name](Socket &listening_socket) { + socket_id_callback(socket_name); + }, + error_ptr); +} - m_waiting_for_accept = true; - llvm::Expected<std::unique_ptr<TCPSocket>> listening_socket = - Socket::TcpListen(s, m_child_processes_inherit, &m_port_predicate); - if (!listening_socket) { - if (error_ptr) - *error_ptr = listening_socket.takeError(); - else - LLDB_LOG_ERROR(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_CONNECTION), - listening_socket.takeError(), "tcp listen failed: {0}"); - return eConnectionStatusError; - } +ConnectionStatus ConnectionFileDescriptor::ConnectNamedSocket( + llvm::StringRef socket_name, socket_id_callback_type socket_id_callback, + Status *error_ptr) { + return ConnectSocket(Socket::ProtocolUnixDomain, socket_name, error_ptr); +} +ConnectionStatus ConnectionFileDescriptor::AcceptAbstractSocket( + llvm::StringRef socket_name, socket_id_callback_type socket_id_callback, + Status *error_ptr) { + return AcceptSocket( + Socket::ProtocolUnixAbstract, socket_name, + [socket_id_callback, socket_name](Socket &listening_socket) { + socket_id_callback(socket_name); + }, + error_ptr); +} - Socket *accepted_socket; - Status error = listening_socket.get()->Accept(accepted_socket); - if (error_ptr) - *error_ptr = error; - if (error.Fail()) - return eConnectionStatusError; +lldb::ConnectionStatus ConnectionFileDescriptor::ConnectAbstractSocket( + llvm::StringRef socket_name, socket_id_callback_type socket_id_callback, + Status *error_ptr) { + return ConnectSocket(Socket::ProtocolUnixAbstract, socket_name, error_ptr); +} - InitializeSocket(accepted_socket); - return eConnectionStatusSuccess; +ConnectionStatus +ConnectionFileDescriptor::AcceptTCP(llvm::StringRef socket_name, + socket_id_callback_type socket_id_callback, + Status *error_ptr) { + ConnectionStatus ret = AcceptSocket( + Socket::ProtocolTcp, socket_name, + [socket_id_callback](Socket &listening_socket) { + uint16_t port = + static_cast<TCPSocket &>(listening_socket).GetLocalPortNumber(); + socket_id_callback(std::to_string(port)); + }, + error_ptr); + if (ret == eConnectionStatusSuccess) + m_uri.assign( + static_cast<TCPSocket *>(m_io_sp.get())->GetRemoteConnectionURI()); + return ret; } -ConnectionStatus ConnectionFileDescriptor::ConnectTCP(llvm::StringRef s, - Status *error_ptr) { +ConnectionStatus +ConnectionFileDescriptor::ConnectTCP(llvm::StringRef socket_name, + socket_id_callback_type socket_id_callback, + Status *error_ptr) { + return ConnectSocket(Socket::ProtocolTcp, socket_name, error_ptr); +} + +ConnectionStatus +ConnectionFileDescriptor::ConnectUDP(llvm::StringRef s, + socket_id_callback_type socket_id_callback, + Status *error_ptr) { if (error_ptr) *error_ptr = Status(); - - llvm::Expected<std::unique_ptr<Socket>> socket = - Socket::TcpConnect(s, m_child_processes_inherit); + llvm::Expected<std::unique_ptr<UDPSocket>> socket = + Socket::UdpConnect(s, m_child_processes_inherit); if (!socket) { if (error_ptr) *error_ptr = socket.takeError(); @@ -737,36 +660,144 @@ ConnectionStatus ConnectionFileDescriptor::ConnectTCP(llvm::StringRef s, socket.takeError(), "tcp connect failed: {0}"); return eConnectionStatusError; } - m_write_sp = std::move(*socket); - m_read_sp = m_write_sp; + m_io_sp = std::move(*socket); m_uri.assign(std::string(s)); return eConnectionStatusSuccess; } -ConnectionStatus ConnectionFileDescriptor::ConnectUDP(llvm::StringRef s, - Status *error_ptr) { +ConnectionStatus +ConnectionFileDescriptor::ConnectFD(llvm::StringRef s, + socket_id_callback_type socket_id_callback, + Status *error_ptr) { +#if LLDB_ENABLE_POSIX + // Just passing a native file descriptor within this current process that + // is already opened (possibly from a service or other source). + int fd = -1; + + if (!s.getAsInteger(0, fd)) { + // We have what looks to be a valid file descriptor, but we should make + // sure it is. We currently are doing this by trying to get the flags + // from the file descriptor and making sure it isn't a bad fd. + errno = 0; + int flags = ::fcntl(fd, F_GETFL, 0); + if (flags == -1 || errno == EBADF) { + if (error_ptr) + error_ptr->SetErrorStringWithFormat("stale file descriptor: %s", + s.str().c_str()); + m_io_sp.reset(); + return eConnectionStatusError; + } else { + // Don't take ownership of a file descriptor that gets passed to us + // since someone else opened the file descriptor and handed it to us. + // TODO: Since are using a URL to open connection we should + // eventually parse options using the web standard where we have + // "fd://123?opt1=value;opt2=value" and we can have an option be + // "owns=1" or "owns=0" or something like this to allow us to specify + // this. For now, we assume we must assume we don't own it. + + std::unique_ptr<TCPSocket> tcp_socket; + tcp_socket = std::make_unique<TCPSocket>(fd, false, false); + // Try and get a socket option from this file descriptor to see if + // this is a socket and set m_is_socket accordingly. + int resuse; + bool is_socket = + !!tcp_socket->GetOption(SOL_SOCKET, SO_REUSEADDR, resuse); + if (is_socket) + m_io_sp = std::move(tcp_socket); + else + m_io_sp = + std::make_shared<NativeFile>(fd, File::eOpenOptionReadWrite, false); + m_uri = s.str(); + return eConnectionStatusSuccess; + } + } + if (error_ptr) - *error_ptr = Status(); - llvm::Expected<std::unique_ptr<UDPSocket>> socket = - Socket::UdpConnect(s, m_child_processes_inherit); - if (!socket) { + error_ptr->SetErrorStringWithFormat("invalid file descriptor: \"%s\"", + s.str().c_str()); + m_io_sp.reset(); + return eConnectionStatusError; +#endif // LLDB_ENABLE_POSIX + llvm_unreachable("this function should be only called w/ LLDB_ENABLE_POSIX"); +} + +ConnectionStatus ConnectionFileDescriptor::ConnectFile( + llvm::StringRef s, socket_id_callback_type socket_id_callback, + Status *error_ptr) { +#if LLDB_ENABLE_POSIX + std::string addr_str = s.str(); + // file:///PATH + int fd = llvm::sys::RetryAfterSignal(-1, ::open, addr_str.c_str(), O_RDWR); + if (fd == -1) { if (error_ptr) - *error_ptr = socket.takeError(); - else - LLDB_LOG_ERROR(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_CONNECTION), - socket.takeError(), "tcp connect failed: {0}"); + error_ptr->SetErrorToErrno(); return eConnectionStatusError; } - m_write_sp = std::move(*socket); - m_read_sp = m_write_sp; - m_uri.assign(std::string(s)); + + if (::isatty(fd)) { + // Set up serial terminal emulation + struct termios options; + ::tcgetattr(fd, &options); + + // Set port speed to maximum + ::cfsetospeed(&options, B115200); + ::cfsetispeed(&options, B115200); + + // Raw input, disable echo and signals + options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); + + // Make sure only one character is needed to return from a read + options.c_cc[VMIN] = 1; + options.c_cc[VTIME] = 0; + + llvm::sys::RetryAfterSignal(-1, ::tcsetattr, fd, TCSANOW, &options); + } + + m_io_sp = std::make_shared<NativeFile>(fd, File::eOpenOptionReadWrite, true); return eConnectionStatusSuccess; +#endif // LLDB_ENABLE_POSIX + llvm_unreachable("this function should be only called w/ LLDB_ENABLE_POSIX"); } -uint16_t -ConnectionFileDescriptor::GetListeningPort(const Timeout<std::micro> &timeout) { - auto Result = m_port_predicate.WaitForValueNotEqualTo(0, timeout); - return Result ? *Result : 0; +ConnectionStatus ConnectionFileDescriptor::ConnectSerialPort( + llvm::StringRef s, socket_id_callback_type socket_id_callback, + Status *error_ptr) { +#if LLDB_ENABLE_POSIX + llvm::StringRef path, qs; + // serial:///PATH?k1=v1&k2=v2... + std::tie(path, qs) = s.split('?'); + + llvm::Expected<SerialPort::Options> serial_options = + SerialPort::OptionsFromURL(qs); + if (!serial_options) { + if (error_ptr) + *error_ptr = serial_options.takeError(); + else + llvm::consumeError(serial_options.takeError()); + return eConnectionStatusError; + } + + int fd = llvm::sys::RetryAfterSignal(-1, ::open, path.str().c_str(), O_RDWR); + if (fd == -1) { + if (error_ptr) + error_ptr->SetErrorToErrno(); + return eConnectionStatusError; + } + + llvm::Expected<std::unique_ptr<SerialPort>> serial_sp = SerialPort::Create( + fd, File::eOpenOptionReadWrite, serial_options.get(), true); + if (!serial_sp) { + if (error_ptr) + *error_ptr = serial_sp.takeError(); + else + llvm::consumeError(serial_sp.takeError()); + return eConnectionStatusError; + } + m_io_sp = std::move(serial_sp.get()); + + return eConnectionStatusSuccess; +#endif // LLDB_ENABLE_POSIX + llvm_unreachable("this function should be only called w/ LLDB_ENABLE_POSIX"); } bool ConnectionFileDescriptor::GetChildProcessesInherit() const { @@ -779,7 +810,6 @@ void ConnectionFileDescriptor::SetChildProcessesInherit( } void ConnectionFileDescriptor::InitializeSocket(Socket *socket) { - m_write_sp.reset(socket); - m_read_sp = m_write_sp; + m_io_sp.reset(socket); m_uri = socket->GetRemoteConnectionURI(); } diff --git a/contrib/llvm-project/lldb/source/Host/posix/DomainSocket.cpp b/contrib/llvm-project/lldb/source/Host/posix/DomainSocket.cpp index 7322b15200b4..ddbd983abb81 100644 --- a/contrib/llvm-project/lldb/source/Host/posix/DomainSocket.cpp +++ b/contrib/llvm-project/lldb/source/Host/posix/DomainSocket.cpp @@ -26,13 +26,11 @@ using namespace lldb_private; #endif #endif // #ifdef __ANDROID__ -namespace { +static const int kDomain = AF_UNIX; +static const int kType = SOCK_STREAM; -const int kDomain = AF_UNIX; -const int kType = SOCK_STREAM; - -bool SetSockAddr(llvm::StringRef name, const size_t name_offset, - sockaddr_un *saddr_un, socklen_t &saddr_un_len) { +static bool SetSockAddr(llvm::StringRef name, const size_t name_offset, + sockaddr_un *saddr_un, socklen_t &saddr_un_len) { if (name.size() + name_offset > sizeof(saddr_un->sun_path)) return false; @@ -56,7 +54,6 @@ bool SetSockAddr(llvm::StringRef name, const size_t name_offset, return true; } -} // namespace DomainSocket::DomainSocket(bool should_close, bool child_processes_inherit) : Socket(ProtocolUnixDomain, should_close, child_processes_inherit) {} @@ -127,29 +124,33 @@ void DomainSocket::DeleteSocketFile(llvm::StringRef name) { } std::string DomainSocket::GetSocketName() const { - if (m_socket != kInvalidSocketValue) { - struct sockaddr_un saddr_un; - saddr_un.sun_family = AF_UNIX; - socklen_t sock_addr_len = sizeof(struct sockaddr_un); - if (::getpeername(m_socket, (struct sockaddr *)&saddr_un, &sock_addr_len) == - 0) { - std::string name(saddr_un.sun_path + GetNameOffset(), - sock_addr_len - - offsetof(struct sockaddr_un, sun_path) - + if (m_socket == kInvalidSocketValue) + return ""; + + struct sockaddr_un saddr_un; + saddr_un.sun_family = AF_UNIX; + socklen_t sock_addr_len = sizeof(struct sockaddr_un); + if (::getpeername(m_socket, (struct sockaddr *)&saddr_un, &sock_addr_len) != + 0) + return ""; + + if (sock_addr_len <= offsetof(struct sockaddr_un, sun_path)) + return ""; // Unnamed domain socket + + llvm::StringRef name(saddr_un.sun_path + GetNameOffset(), + sock_addr_len - offsetof(struct sockaddr_un, sun_path) - GetNameOffset()); - if (name.back() == '\0') name.pop_back(); - return name; - } - } - return ""; + name = name.rtrim('\0'); + + return name.str(); } std::string DomainSocket::GetRemoteConnectionURI() const { - if (m_socket != kInvalidSocketValue) { - return std::string(llvm::formatv( - "{0}://{1}", - GetNameOffset() == 0 ? "unix-connect" : "unix-abstract-connect", - GetSocketName())); - } - return ""; + std::string name = GetSocketName(); + if (name.empty()) + return name; + + return llvm::formatv( + "{0}://{1}", + GetNameOffset() == 0 ? "unix-connect" : "unix-abstract-connect", name); } diff --git a/contrib/llvm-project/lldb/source/Host/posix/HostInfoPosix.cpp b/contrib/llvm-project/lldb/source/Host/posix/HostInfoPosix.cpp index b633acf6fec6..63553590dff5 100644 --- a/contrib/llvm-project/lldb/source/Host/posix/HostInfoPosix.cpp +++ b/contrib/llvm-project/lldb/source/Host/posix/HostInfoPosix.cpp @@ -21,6 +21,7 @@ #include <mutex> #include <pwd.h> #include <sys/types.h> +#include <sys/utsname.h> #include <unistd.h> using namespace lldb_private; @@ -37,6 +38,14 @@ bool HostInfoPosix::GetHostname(std::string &s) { return false; } +llvm::Optional<std::string> HostInfoPosix::GetOSKernelDescription() { + struct utsname un; + if (uname(&un) < 0) + return llvm::None; + + return std::string(un.version); +} + #ifdef __ANDROID__ #include <android/api-level.h> #endif diff --git a/contrib/llvm-project/lldb/source/Host/posix/HostProcessPosix.cpp b/contrib/llvm-project/lldb/source/Host/posix/HostProcessPosix.cpp index f0142ec946b7..8599a94d2241 100644 --- a/contrib/llvm-project/lldb/source/Host/posix/HostProcessPosix.cpp +++ b/contrib/llvm-project/lldb/source/Host/posix/HostProcessPosix.cpp @@ -18,9 +18,7 @@ using namespace lldb_private; -namespace { -const int kInvalidPosixProcess = 0; -} +static const int kInvalidPosixProcess = 0; HostProcessPosix::HostProcessPosix() : HostNativeProcessBase(kInvalidPosixProcess) {} diff --git a/contrib/llvm-project/lldb/source/Host/posix/LockFilePosix.cpp b/contrib/llvm-project/lldb/source/Host/posix/LockFilePosix.cpp index d197974a72a5..cb9ca5c29e5f 100644 --- a/contrib/llvm-project/lldb/source/Host/posix/LockFilePosix.cpp +++ b/contrib/llvm-project/lldb/source/Host/posix/LockFilePosix.cpp @@ -16,10 +16,8 @@ using namespace lldb; using namespace lldb_private; -namespace { - -Status fileLock(int fd, int cmd, int lock_type, const uint64_t start, - const uint64_t len) { +static Status fileLock(int fd, int cmd, int lock_type, const uint64_t start, + const uint64_t len) { struct flock fl; fl.l_type = lock_type; @@ -35,8 +33,6 @@ Status fileLock(int fd, int cmd, int lock_type, const uint64_t start, return error; } -} // namespace - LockFilePosix::LockFilePosix(int fd) : LockFileBase(fd) {} LockFilePosix::~LockFilePosix() { Unlock(); } diff --git a/contrib/llvm-project/lldb/source/Host/posix/PipePosix.cpp b/contrib/llvm-project/lldb/source/Host/posix/PipePosix.cpp index a8cce573f12a..bd311ad8769a 100644 --- a/contrib/llvm-project/lldb/source/Host/posix/PipePosix.cpp +++ b/contrib/llvm-project/lldb/source/Host/posix/PipePosix.cpp @@ -38,12 +38,10 @@ enum PIPES { READ, WRITE }; // Constants 0 and 1 for READ and WRITE #define PIPE2_SUPPORTED 0 #endif -namespace { - -constexpr auto OPEN_WRITER_SLEEP_TIMEOUT_MSECS = 100; +static constexpr auto OPEN_WRITER_SLEEP_TIMEOUT_MSECS = 100; #if defined(FD_CLOEXEC) && !PIPE2_SUPPORTED -bool SetCloexecFlag(int fd) { +static bool SetCloexecFlag(int fd) { int flags = ::fcntl(fd, F_GETFD); if (flags == -1) return false; @@ -51,10 +49,9 @@ bool SetCloexecFlag(int fd) { } #endif -std::chrono::time_point<std::chrono::steady_clock> Now() { +static std::chrono::time_point<std::chrono::steady_clock> Now() { return std::chrono::steady_clock::now(); } -} // namespace PipePosix::PipePosix() : m_fds{PipePosix::kInvalidDescriptor, PipePosix::kInvalidDescriptor} {} diff --git a/contrib/llvm-project/lldb/source/Host/posix/ProcessLauncherPosixFork.cpp b/contrib/llvm-project/lldb/source/Host/posix/ProcessLauncherPosixFork.cpp index 25dcf1e592c5..63178e6c8a7a 100644 --- a/contrib/llvm-project/lldb/source/Host/posix/ProcessLauncherPosixFork.cpp +++ b/contrib/llvm-project/lldb/source/Host/posix/ProcessLauncherPosixFork.cpp @@ -14,6 +14,7 @@ #include "lldb/Utility/FileSpec.h" #include "lldb/Utility/Log.h" #include "llvm/Support/Errno.h" +#include "llvm/Support/FileSystem.h" #include <climits> #include <sys/ptrace.h> @@ -46,8 +47,8 @@ static void FixupEnvironment(Environment &env) { #endif } -static void LLVM_ATTRIBUTE_NORETURN ExitWithError(int error_fd, - const char *operation) { +[[noreturn]] static void ExitWithError(int error_fd, + const char *operation) { int err = errno; llvm::raw_fd_ostream os(error_fd, true); os << operation << " failed: " << llvm::sys::StrError(err); @@ -88,8 +89,8 @@ static void DupDescriptor(int error_fd, const FileSpec &file_spec, int fd, return; } -static void LLVM_ATTRIBUTE_NORETURN ChildFunc(int error_fd, - const ProcessLaunchInfo &info) { +[[noreturn]] static void ChildFunc(int error_fd, + const ProcessLaunchInfo &info) { if (info.GetFlags().Test(eLaunchFlagLaunchInSeparateProcessGroup)) { if (setpgid(0, 0) != 0) ExitWithError(error_fd, "setpgid"); @@ -143,9 +144,32 @@ static void LLVM_ATTRIBUTE_NORETURN ChildFunc(int error_fd, // Close everything besides stdin, stdout, and stderr that has no file // action to avoid leaking. Only do this when debugging, as elsewhere we // actually rely on passing open descriptors to child processes. - for (int fd = 3; fd < sysconf(_SC_OPEN_MAX); ++fd) - if (!info.GetFileActionForFD(fd) && fd != error_fd) - close(fd); + + const llvm::StringRef proc_fd_path = "/proc/self/fd"; + std::error_code ec; + bool result; + ec = llvm::sys::fs::is_directory(proc_fd_path, result); + if (result) { + std::vector<int> files_to_close; + // Directory iterator doesn't ensure any sequence. + for (llvm::sys::fs::directory_iterator iter(proc_fd_path, ec), file_end; + iter != file_end && !ec; iter.increment(ec)) { + int fd = std::stoi(iter->path().substr(proc_fd_path.size() + 1)); + + // Don't close first three entries since they are stdin, stdout and + // stderr. + if (fd > 2 && !info.GetFileActionForFD(fd) && fd != error_fd) + files_to_close.push_back(fd); + } + for (int file_to_close : files_to_close) + close(file_to_close); + } else { + // Since /proc/self/fd didn't work, trying the slow way instead. + int max_fd = sysconf(_SC_OPEN_MAX); + for (int fd = 3; fd < max_fd; ++fd) + if (!info.GetFileActionForFD(fd) && fd != error_fd) + close(fd); + } // Start tracing this child that is about to exec. if (ptrace(PT_TRACE_ME, 0, nullptr, 0) == -1) diff --git a/contrib/llvm-project/lldb/source/Interpreter/CommandInterpreter.cpp b/contrib/llvm-project/lldb/source/Interpreter/CommandInterpreter.cpp index 00e9ccb762c3..301bf949feef 100644 --- a/contrib/llvm-project/lldb/source/Interpreter/CommandInterpreter.cpp +++ b/contrib/llvm-project/lldb/source/Interpreter/CommandInterpreter.cpp @@ -744,8 +744,10 @@ void CommandInterpreter::LoadCommandDictionary() { std::unique_ptr<CommandObjectRegexCommand> connect_gdb_remote_cmd_up( new CommandObjectRegexCommand( *this, "gdb-remote", - "Connect to a process via remote GDB server. " - "If no host is specifed, localhost is assumed.", + "Connect to a process via remote GDB server.\n" + "If no host is specifed, localhost is assumed.\n" + "gdb-remote is an abbreviation for 'process connect --plugin " + "gdb-remote connect://<hostname>:<port>'\n", "gdb-remote [<hostname>:]<portnum>", 2, 0, false)); if (connect_gdb_remote_cmd_up) { if (connect_gdb_remote_cmd_up->AddRegexCommand( @@ -762,9 +764,10 @@ void CommandInterpreter::LoadCommandDictionary() { std::unique_ptr<CommandObjectRegexCommand> connect_kdp_remote_cmd_up( new CommandObjectRegexCommand( *this, "kdp-remote", - "Connect to a process via remote KDP server. " - "If no UDP port is specified, port 41139 is " - "assumed.", + "Connect to a process via remote KDP server.\n" + "If no UDP port is specified, port 41139 is assumed.\n" + "kdp-remote is an abbreviation for 'process connect --plugin " + "kdp-remote udp://<hostname>:<port>'\n", "kdp-remote <hostname>[:<portnum>]", 2, 0, false)); if (connect_kdp_remote_cmd_up) { if (connect_kdp_remote_cmd_up->AddRegexCommand( @@ -897,6 +900,63 @@ int CommandInterpreter::GetCommandNamesMatchingPartialString( return matches.GetSize(); } +CommandObjectMultiword *CommandInterpreter::VerifyUserMultiwordCmdPath( + Args &path, bool leaf_is_command, Status &result) { + result.Clear(); + + auto get_multi_or_report_error = + [&result](CommandObjectSP cmd_sp, + const char *name) -> CommandObjectMultiword * { + if (!cmd_sp) { + result.SetErrorStringWithFormat("Path component: '%s' not found", name); + return nullptr; + } + if (!cmd_sp->IsUserCommand()) { + result.SetErrorStringWithFormat("Path component: '%s' is not a user " + "command", + name); + return nullptr; + } + CommandObjectMultiword *cmd_as_multi = cmd_sp->GetAsMultiwordCommand(); + if (!cmd_as_multi) { + result.SetErrorStringWithFormat("Path component: '%s' is not a container " + "command", + name); + return nullptr; + } + return cmd_as_multi; + }; + + size_t num_args = path.GetArgumentCount(); + if (num_args == 0) { + result.SetErrorString("empty command path"); + return nullptr; + } + + if (num_args == 1 && leaf_is_command) { + // We just got a leaf command to be added to the root. That's not an error, + // just return null for the container. + return nullptr; + } + + // Start by getting the root command from the interpreter. + const char *cur_name = path.GetArgumentAtIndex(0); + CommandObjectSP cur_cmd_sp = GetCommandSPExact(cur_name); + CommandObjectMultiword *cur_as_multi = + get_multi_or_report_error(cur_cmd_sp, cur_name); + if (cur_as_multi == nullptr) + return nullptr; + + size_t num_path_elements = num_args - (leaf_is_command ? 1 : 0); + for (size_t cursor = 1; cursor < num_path_elements && cur_as_multi != nullptr; + cursor++) { + cur_name = path.GetArgumentAtIndex(cursor); + cur_cmd_sp = cur_as_multi->GetSubcommandSPExact(cur_name); + cur_as_multi = get_multi_or_report_error(cur_cmd_sp, cur_name); + } + return cur_as_multi; +} + CommandObjectSP CommandInterpreter::GetCommandSP(llvm::StringRef cmd_str, bool include_aliases, bool exact, StringList *matches, @@ -923,10 +983,17 @@ CommandInterpreter::GetCommandSP(llvm::StringRef cmd_str, bool include_aliases, command_sp = pos->second; } + if (HasUserMultiwordCommands()) { + auto pos = m_user_mw_dict.find(cmd); + if (pos != m_user_mw_dict.end()) + command_sp = pos->second; + } + if (!exact && !command_sp) { // We will only get into here if we didn't find any exact matches. - CommandObjectSP user_match_sp, alias_match_sp, real_match_sp; + CommandObjectSP user_match_sp, user_mw_match_sp, alias_match_sp, + real_match_sp; StringList local_matches; if (matches == nullptr) @@ -935,6 +1002,7 @@ CommandInterpreter::GetCommandSP(llvm::StringRef cmd_str, bool include_aliases, unsigned int num_cmd_matches = 0; unsigned int num_alias_matches = 0; unsigned int num_user_matches = 0; + unsigned int num_user_mw_matches = 0; // Look through the command dictionaries one by one, and if we get only one // match from any of them in toto, then return that, otherwise return an @@ -978,14 +1046,32 @@ CommandInterpreter::GetCommandSP(llvm::StringRef cmd_str, bool include_aliases, user_match_sp = pos->second; } + if (HasUserMultiwordCommands()) { + num_user_mw_matches = AddNamesMatchingPartialString( + m_user_mw_dict, cmd_str, *matches, descriptions); + } + + if (num_user_mw_matches == 1) { + cmd.assign(matches->GetStringAtIndex(num_cmd_matches + num_alias_matches + + num_user_matches)); + + auto pos = m_user_mw_dict.find(cmd); + if (pos != m_user_mw_dict.end()) + user_mw_match_sp = pos->second; + } + // If we got exactly one match, return that, otherwise return the match // list. - if (num_user_matches + num_cmd_matches + num_alias_matches == 1) { + if (num_user_matches + num_user_mw_matches + num_cmd_matches + + num_alias_matches == + 1) { if (num_cmd_matches) return real_match_sp; else if (num_alias_matches) return alias_match_sp; + else if (num_user_mw_matches) + return user_mw_match_sp; else return user_match_sp; } @@ -1008,6 +1094,8 @@ bool CommandInterpreter::AddCommand(llvm::StringRef name, if (name.empty()) return false; + cmd_sp->SetIsUserCommand(false); + std::string name_sstr(name); auto name_iter = m_command_dict.find(name_sstr); if (name_iter != m_command_dict.end()) { @@ -1020,33 +1108,49 @@ bool CommandInterpreter::AddCommand(llvm::StringRef name, return true; } -bool CommandInterpreter::AddUserCommand(llvm::StringRef name, - const lldb::CommandObjectSP &cmd_sp, - bool can_replace) { +Status CommandInterpreter::AddUserCommand(llvm::StringRef name, + const lldb::CommandObjectSP &cmd_sp, + bool can_replace) { + Status result; if (cmd_sp.get()) lldbassert((this == &cmd_sp->GetCommandInterpreter()) && "tried to add a CommandObject from a different interpreter"); - - if (!name.empty()) { - // do not allow replacement of internal commands - if (CommandExists(name)) { - if (!can_replace) - return false; - if (!m_command_dict[std::string(name)]->IsRemovable()) - return false; + if (name.empty()) { + result.SetErrorString("can't use the empty string for a command name"); + return result; + } + // do not allow replacement of internal commands + if (CommandExists(name)) { + result.SetErrorString("can't replace builtin command"); + return result; + } + + if (UserCommandExists(name)) { + if (!can_replace) { + result.SetErrorString("user command exists and force replace not set"); + return result; + } + if (cmd_sp->IsMultiwordObject()) { + if (!m_user_mw_dict[std::string(name)]->IsRemovable()) { + result.SetErrorString( + "can't replace explicitly non-removable multi-word command"); + return result; + } + } else { + if (!m_user_dict[std::string(name)]->IsRemovable()) { + result.SetErrorString("can't replace explicitly non-removable command"); + return result; + } } + } - if (UserCommandExists(name)) { - if (!can_replace) - return false; - if (!m_user_dict[std::string(name)]->IsRemovable()) - return false; - } + cmd_sp->SetIsUserCommand(true); + if (cmd_sp->IsMultiwordObject()) + m_user_mw_dict[std::string(name)] = cmd_sp; + else m_user_dict[std::string(name)] = cmd_sp; - return true; - } - return false; + return result; } CommandObjectSP @@ -1127,6 +1231,42 @@ CommandInterpreter::GetCommandObject(llvm::StringRef cmd_str, return GetCommandSP(cmd_str, true, false, matches, descriptions).get(); } +CommandObject *CommandInterpreter::GetUserCommandObject( + llvm::StringRef cmd, StringList *matches, StringList *descriptions) const { + std::string cmd_str(cmd); + auto find_exact = [&](const CommandObject::CommandMap &map) { + auto found_elem = map.find(std::string(cmd)); + if (found_elem == map.end()) + return (CommandObject *)nullptr; + CommandObject *exact_cmd = found_elem->second.get(); + if (exact_cmd) { + if (matches) + matches->AppendString(exact_cmd->GetCommandName()); + if (descriptions) + descriptions->AppendString(exact_cmd->GetHelp()); + return exact_cmd; + } + return (CommandObject *)nullptr; + }; + + CommandObject *exact_cmd = find_exact(GetUserCommands()); + if (exact_cmd) + return exact_cmd; + + exact_cmd = find_exact(GetUserMultiwordCommands()); + if (exact_cmd) + return exact_cmd; + + // We didn't have an exact command, so now look for partial matches. + StringList tmp_list; + StringList *matches_ptr = matches ? matches : &tmp_list; + AddNamesMatchingPartialString(GetUserCommands(), cmd_str, *matches_ptr); + AddNamesMatchingPartialString(GetUserMultiwordCommands(), + cmd_str, *matches_ptr); + + return {}; +} + bool CommandInterpreter::CommandExists(llvm::StringRef cmd) const { return m_command_dict.find(std::string(cmd)) != m_command_dict.end(); } @@ -1169,6 +1309,10 @@ bool CommandInterpreter::UserCommandExists(llvm::StringRef cmd) const { return m_user_dict.find(std::string(cmd)) != m_user_dict.end(); } +bool CommandInterpreter::UserMultiwordCommandExists(llvm::StringRef cmd) const { + return m_user_mw_dict.find(std::string(cmd)) != m_user_mw_dict.end(); +} + CommandAlias * CommandInterpreter::AddAlias(llvm::StringRef alias_name, lldb::CommandObjectSP &command_obj_sp, @@ -1209,9 +1353,10 @@ bool CommandInterpreter::RemoveCommand(llvm::StringRef cmd) { } return false; } -bool CommandInterpreter::RemoveUser(llvm::StringRef alias_name) { + +bool CommandInterpreter::RemoveUser(llvm::StringRef user_name) { CommandObject::CommandMap::iterator pos = - m_user_dict.find(std::string(alias_name)); + m_user_dict.find(std::string(user_name)); if (pos != m_user_dict.end()) { m_user_dict.erase(pos); return true; @@ -1219,6 +1364,16 @@ bool CommandInterpreter::RemoveUser(llvm::StringRef alias_name) { return false; } +bool CommandInterpreter::RemoveUserMultiword(llvm::StringRef multi_name) { + CommandObject::CommandMap::iterator pos = + m_user_mw_dict.find(std::string(multi_name)); + if (pos != m_user_mw_dict.end()) { + m_user_mw_dict.erase(pos); + return true; + } + return false; +} + void CommandInterpreter::GetHelp(CommandReturnObject &result, uint32_t cmd_types) { llvm::StringRef help_prologue(GetDebugger().GetIOHandlerHelpPrologue()); @@ -1274,6 +1429,18 @@ void CommandInterpreter::GetHelp(CommandReturnObject &result, result.AppendMessage(""); } + if (!m_user_mw_dict.empty() && + ((cmd_types & eCommandTypesUserMW) == eCommandTypesUserMW)) { + result.AppendMessage("Current user-defined container commands:"); + result.AppendMessage(""); + max_len = FindLongestCommandWord(m_user_mw_dict); + for (pos = m_user_dict.begin(); pos != m_user_mw_dict.end(); ++pos) { + OutputFormattedHelpText(result.GetOutputStream(), pos->first, "--", + pos->second->GetHelp(), max_len); + } + result.AppendMessage(""); + } + result.AppendMessageWithFormat( "For more information on any command, type '%shelp <command-name>'.\n", GetCommandPrefix()); @@ -1931,6 +2098,10 @@ bool CommandInterpreter::HasAliases() const { return (!m_alias_dict.empty()); } bool CommandInterpreter::HasUserCommands() const { return (!m_user_dict.empty()); } +bool CommandInterpreter::HasUserMultiwordCommands() const { + return (!m_user_mw_dict.empty()); +} + bool CommandInterpreter::HasAliasOptions() const { return HasAliases(); } void CommandInterpreter::BuildAliasCommandArgs(CommandObject *alias_cmd_obj, @@ -2113,13 +2284,6 @@ static void GetCwdInitFile(llvm::SmallVectorImpl<char> &init_file) { FileSystem::Instance().Resolve(init_file); } -static LoadCWDlldbinitFile ShouldLoadCwdInitFile() { - lldb::TargetPropertiesSP properties = Target::GetGlobalProperties(); - if (!properties) - return eLoadCWDlldbinitFalse; - return properties->GetLoadCWDlldbinitFile(); -} - void CommandInterpreter::SourceInitFile(FileSpec file, CommandReturnObject &result) { assert(!m_skip_lldbinit_files); @@ -2155,7 +2319,8 @@ void CommandInterpreter::SourceInitFileCwd(CommandReturnObject &result) { return; } - LoadCWDlldbinitFile should_load = ShouldLoadCwdInitFile(); + LoadCWDlldbinitFile should_load = + Target::GetGlobalProperties().GetLoadCWDlldbinitFile(); switch (should_load) { case eLoadCWDlldbinitFalse: @@ -2433,7 +2598,7 @@ void CommandInterpreter::HandleCommandsFromFile(FileSpec &cmd_file, std::string cmd_file_path = cmd_file.GetPath(); auto input_file_up = - FileSystem::Instance().Open(cmd_file, File::eOpenOptionRead); + FileSystem::Instance().Open(cmd_file, File::eOpenOptionReadOnly); if (!input_file_up) { std::string error = llvm::toString(input_file_up.takeError()); result.AppendErrorWithFormatv( @@ -2587,6 +2752,9 @@ void CommandInterpreter::OutputFormattedHelpText(Stream &strm, strm.IndentMore(prefix.size()); bool prefixed_yet = false; + // Even if we have no help text we still want to emit the command name. + if (help_text.empty()) + help_text = "No help text"; while (!help_text.empty()) { // Prefix the first line, indent subsequent lines to line up if (!prefixed_yet) { @@ -2706,7 +2874,8 @@ void CommandInterpreter::FindCommandsForApropos(llvm::StringRef search_word, StringList &commands_help, bool search_builtin_commands, bool search_user_commands, - bool search_alias_commands) { + bool search_alias_commands, + bool search_user_mw_commands) { CommandObject::CommandMap::const_iterator pos; if (search_builtin_commands) @@ -2717,6 +2886,10 @@ void CommandInterpreter::FindCommandsForApropos(llvm::StringRef search_word, FindCommandsForApropos(search_word, commands_found, commands_help, m_user_dict); + if (search_user_mw_commands) + FindCommandsForApropos(search_word, commands_found, commands_help, + m_user_mw_dict); + if (search_alias_commands) FindCommandsForApropos(search_word, commands_found, commands_help, m_alias_dict); @@ -2954,7 +3127,7 @@ bool CommandInterpreter::SaveTranscript( return false; }; - File::OpenOptions flags = File::eOpenOptionWrite | + File::OpenOptions flags = File::eOpenOptionWriteOnly | File::eOpenOptionCanCreate | File::eOpenOptionTruncate; diff --git a/contrib/llvm-project/lldb/source/Interpreter/CommandObject.cpp b/contrib/llvm-project/lldb/source/Interpreter/CommandObject.cpp index a7dcd5682701..64b23d04abea 100644 --- a/contrib/llvm-project/lldb/source/Interpreter/CommandObject.cpp +++ b/contrib/llvm-project/lldb/source/Interpreter/CommandObject.cpp @@ -1120,7 +1120,7 @@ CommandObject::ArgumentTableEntry CommandObject::g_arguments_data[] = { { eArgTypeWatchpointIDRange, "watchpt-id-list", CommandCompletions::eNoCompletion, { nullptr, false }, "For example, '1-3' or '1 to 3'." }, { eArgTypeWatchType, "watch-type", CommandCompletions::eNoCompletion, { nullptr, false }, "Specify the type for a watchpoint." }, { eArgRawInput, "raw-input", CommandCompletions::eNoCompletion, { nullptr, false }, "Free-form text passed to a command without prior interpretation, allowing spaces without requiring quotes. To pass arguments and free form text put two dashes ' -- ' between the last argument and any raw input." }, - { eArgTypeCommand, "command", CommandCompletions::eNoCompletion, { nullptr, false }, "An LLDB Command line command." }, + { eArgTypeCommand, "command", CommandCompletions::eNoCompletion, { nullptr, false }, "An LLDB Command line command element." }, { eArgTypeColumnNum, "column", CommandCompletions::eNoCompletion, { nullptr, false }, "Column number in a source file." }, { eArgTypeModuleUUID, "module-uuid", CommandCompletions::eModuleUUIDCompletion, { nullptr, false }, "A module UUID value." }, { eArgTypeSaveCoreStyle, "corefile-style", CommandCompletions::eNoCompletion, { nullptr, false }, "The type of corefile that lldb will try to create, dependant on this target's capabilities." } diff --git a/contrib/llvm-project/lldb/source/Interpreter/OptionValueArray.cpp b/contrib/llvm-project/lldb/source/Interpreter/OptionValueArray.cpp index b1545bdebf10..4468fe57702e 100644 --- a/contrib/llvm-project/lldb/source/Interpreter/OptionValueArray.cpp +++ b/contrib/llvm-project/lldb/source/Interpreter/OptionValueArray.cpp @@ -8,7 +8,6 @@ #include "lldb/Interpreter/OptionValueArray.h" -#include "lldb/Host/StringConvert.h" #include "lldb/Utility/Args.h" #include "lldb/Utility/Stream.h" @@ -167,13 +166,12 @@ Status OptionValueArray::SetArgs(const Args &args, VarSetOperationType op) { case eVarSetOperationInsertBefore: case eVarSetOperationInsertAfter: if (argc > 1) { - uint32_t idx = - StringConvert::ToUInt32(args.GetArgumentAtIndex(0), UINT32_MAX); + uint32_t idx; const uint32_t count = GetSize(); - if (idx > count) { + if (!llvm::to_integer(args.GetArgumentAtIndex(0), idx) || idx > count) { error.SetErrorStringWithFormat( - "invalid insert array index %u, index must be 0 through %u", idx, - count); + "invalid insert array index %s, index must be 0 through %u", + args.GetArgumentAtIndex(0), count); } else { if (op == eVarSetOperationInsertAfter) ++idx; @@ -207,9 +205,8 @@ Status OptionValueArray::SetArgs(const Args &args, VarSetOperationType op) { bool all_indexes_valid = true; size_t i; for (i = 0; i < argc; ++i) { - const size_t idx = - StringConvert::ToSInt32(args.GetArgumentAtIndex(i), INT32_MAX); - if (idx >= size) { + size_t idx; + if (!llvm::to_integer(args.GetArgumentAtIndex(i), idx) || idx >= size) { all_indexes_valid = false; break; } else @@ -249,13 +246,12 @@ Status OptionValueArray::SetArgs(const Args &args, VarSetOperationType op) { case eVarSetOperationReplace: if (argc > 1) { - uint32_t idx = - StringConvert::ToUInt32(args.GetArgumentAtIndex(0), UINT32_MAX); + uint32_t idx; const uint32_t count = GetSize(); - if (idx > count) { + if (!llvm::to_integer(args.GetArgumentAtIndex(0), idx) || idx > count) { error.SetErrorStringWithFormat( - "invalid replace array index %u, index must be 0 through %u", idx, - count); + "invalid replace array index %s, index must be 0 through %u", + args.GetArgumentAtIndex(0), count); } else { for (size_t i = 1; i < argc; ++i, ++idx) { lldb::OptionValueSP value_sp(CreateValueFromCStringForTypeMask( diff --git a/contrib/llvm-project/lldb/source/Interpreter/OptionValueFileSpecList.cpp b/contrib/llvm-project/lldb/source/Interpreter/OptionValueFileSpecList.cpp index 2160fd61d428..6566eee09d73 100644 --- a/contrib/llvm-project/lldb/source/Interpreter/OptionValueFileSpecList.cpp +++ b/contrib/llvm-project/lldb/source/Interpreter/OptionValueFileSpecList.cpp @@ -8,7 +8,6 @@ #include "lldb/Interpreter/OptionValueFileSpecList.h" -#include "lldb/Host/StringConvert.h" #include "lldb/Utility/Args.h" #include "lldb/Utility/Stream.h" @@ -57,13 +56,12 @@ Status OptionValueFileSpecList::SetValueFromString(llvm::StringRef value, case eVarSetOperationReplace: if (argc > 1) { - uint32_t idx = - StringConvert::ToUInt32(args.GetArgumentAtIndex(0), UINT32_MAX); + uint32_t idx; const uint32_t count = m_current_value.GetSize(); - if (idx > count) { + if (!llvm::to_integer(args.GetArgumentAtIndex(0), idx) || idx > count) { error.SetErrorStringWithFormat( - "invalid file list index %u, index must be 0 through %u", idx, - count); + "invalid file list index %s, index must be 0 through %u", + args.GetArgumentAtIndex(0), count); } else { for (size_t i = 1; i < argc; ++i, ++idx) { FileSpec file(args.GetArgumentAtIndex(i)); @@ -101,13 +99,12 @@ Status OptionValueFileSpecList::SetValueFromString(llvm::StringRef value, case eVarSetOperationInsertBefore: case eVarSetOperationInsertAfter: if (argc > 1) { - uint32_t idx = - StringConvert::ToUInt32(args.GetArgumentAtIndex(0), UINT32_MAX); + uint32_t idx; const uint32_t count = m_current_value.GetSize(); - if (idx > count) { + if (!llvm::to_integer(args.GetArgumentAtIndex(0), idx) || idx > count) { error.SetErrorStringWithFormat( - "invalid insert file list index %u, index must be 0 through %u", - idx, count); + "invalid insert file list index %s, index must be 0 through %u", + args.GetArgumentAtIndex(0), count); } else { if (op == eVarSetOperationInsertAfter) ++idx; @@ -129,9 +126,8 @@ Status OptionValueFileSpecList::SetValueFromString(llvm::StringRef value, bool all_indexes_valid = true; size_t i; for (i = 0; all_indexes_valid && i < argc; ++i) { - const int idx = - StringConvert::ToSInt32(args.GetArgumentAtIndex(i), INT32_MAX); - if (idx == INT32_MAX) + int idx; + if (!llvm::to_integer(args.GetArgumentAtIndex(i), idx)) all_indexes_valid = false; else remove_indexes.push_back(idx); diff --git a/contrib/llvm-project/lldb/source/Interpreter/OptionValuePathMappings.cpp b/contrib/llvm-project/lldb/source/Interpreter/OptionValuePathMappings.cpp index 4dceb5632716..543b0e1b8ea8 100644 --- a/contrib/llvm-project/lldb/source/Interpreter/OptionValuePathMappings.cpp +++ b/contrib/llvm-project/lldb/source/Interpreter/OptionValuePathMappings.cpp @@ -9,21 +9,19 @@ #include "lldb/Interpreter/OptionValuePathMappings.h" #include "lldb/Host/FileSystem.h" -#include "lldb/Host/StringConvert.h" #include "lldb/Utility/Args.h" #include "lldb/Utility/FileSpec.h" #include "lldb/Utility/Stream.h" using namespace lldb; using namespace lldb_private; -namespace { + static bool VerifyPathExists(const char *path) { if (path && path[0]) return FileSystem::Instance().Exists(path); else return false; } -} void OptionValuePathMappings::DumpValue(const ExecutionContext *exe_ctx, Stream &strm, uint32_t dump_mask) { @@ -52,23 +50,22 @@ Status OptionValuePathMappings::SetValueFromString(llvm::StringRef value, // Must be at least one index + 1 pair of paths, and the pair count must be // even if (argc >= 3 && (((argc - 1) & 1) == 0)) { - uint32_t idx = - StringConvert::ToUInt32(args.GetArgumentAtIndex(0), UINT32_MAX); + uint32_t idx; const uint32_t count = m_path_mappings.GetSize(); - if (idx > count) { + if (!llvm::to_integer(args.GetArgumentAtIndex(0), idx) || idx > count) { error.SetErrorStringWithFormat( - "invalid file list index %u, index must be 0 through %u", idx, - count); + "invalid file list index %s, index must be 0 through %u", + args.GetArgumentAtIndex(0), count); } else { bool changed = false; for (size_t i = 1; i < argc; idx++, i += 2) { const char *orginal_path = args.GetArgumentAtIndex(i); const char *replace_path = args.GetArgumentAtIndex(i + 1); if (VerifyPathExists(replace_path)) { - ConstString a(orginal_path); - ConstString b(replace_path); - if (!m_path_mappings.Replace(a, b, idx, m_notify_changes)) - m_path_mappings.Append(a, b, m_notify_changes); + if (!m_path_mappings.Replace(orginal_path, replace_path, idx, + m_notify_changes)) + m_path_mappings.Append(orginal_path, replace_path, + m_notify_changes); changed = true; } else { std::string previousError = @@ -105,9 +102,7 @@ Status OptionValuePathMappings::SetValueFromString(llvm::StringRef value, const char *orginal_path = args.GetArgumentAtIndex(i); const char *replace_path = args.GetArgumentAtIndex(i + 1); if (VerifyPathExists(replace_path)) { - ConstString a(orginal_path); - ConstString b(replace_path); - m_path_mappings.Append(a, b, m_notify_changes); + m_path_mappings.Append(orginal_path, replace_path, m_notify_changes); m_value_was_set = true; changed = true; } else { @@ -128,13 +123,12 @@ Status OptionValuePathMappings::SetValueFromString(llvm::StringRef value, // Must be at least one index + 1 pair of paths, and the pair count must be // even if (argc >= 3 && (((argc - 1) & 1) == 0)) { - uint32_t idx = - StringConvert::ToUInt32(args.GetArgumentAtIndex(0), UINT32_MAX); + uint32_t idx; const uint32_t count = m_path_mappings.GetSize(); - if (idx > count) { + if (!llvm::to_integer(args.GetArgumentAtIndex(0), idx) || idx > count) { error.SetErrorStringWithFormat( - "invalid file list index %u, index must be 0 through %u", idx, - count); + "invalid file list index %s, index must be 0 through %u", + args.GetArgumentAtIndex(0), count); } else { bool changed = false; if (op == eVarSetOperationInsertAfter) @@ -143,9 +137,8 @@ Status OptionValuePathMappings::SetValueFromString(llvm::StringRef value, const char *orginal_path = args.GetArgumentAtIndex(i); const char *replace_path = args.GetArgumentAtIndex(i + 1); if (VerifyPathExists(replace_path)) { - ConstString a(orginal_path); - ConstString b(replace_path); - m_path_mappings.Insert(a, b, idx, m_notify_changes); + m_path_mappings.Insert(orginal_path, replace_path, idx, + m_notify_changes); changed = true; idx++; } else { @@ -169,9 +162,9 @@ Status OptionValuePathMappings::SetValueFromString(llvm::StringRef value, if (argc > 0) { std::vector<int> remove_indexes; for (size_t i = 0; i < argc; ++i) { - int idx = - StringConvert::ToSInt32(args.GetArgumentAtIndex(i), INT32_MAX); - if (idx < 0 || idx >= (int)m_path_mappings.GetSize()) { + int idx; + if (!llvm::to_integer(args.GetArgumentAtIndex(i), idx) || idx < 0 || + idx >= (int)m_path_mappings.GetSize()) { error.SetErrorStringWithFormat( "invalid array index '%s', aborting remove operation", args.GetArgumentAtIndex(i)); diff --git a/contrib/llvm-project/lldb/source/Interpreter/OptionValueProperties.cpp b/contrib/llvm-project/lldb/source/Interpreter/OptionValueProperties.cpp index ae073798ca12..1a8f2f0ab180 100644 --- a/contrib/llvm-project/lldb/source/Interpreter/OptionValueProperties.cpp +++ b/contrib/llvm-project/lldb/source/Interpreter/OptionValueProperties.cpp @@ -48,7 +48,8 @@ void OptionValueProperties::AppendProperty(ConstString name, ConstString desc, bool is_global, const OptionValueSP &value_sp) { - Property property(name, desc, is_global, value_sp); + Property property(name.GetStringRef(), desc.GetStringRef(), is_global, + value_sp); m_name_to_index.Append(name, m_properties.size()); m_properties.push_back(property); value_sp->SetParent(shared_from_this()); diff --git a/contrib/llvm-project/lldb/source/Interpreter/OptionValueSInt64.cpp b/contrib/llvm-project/lldb/source/Interpreter/OptionValueSInt64.cpp index b875ba8e3536..c1db5056cd94 100644 --- a/contrib/llvm-project/lldb/source/Interpreter/OptionValueSInt64.cpp +++ b/contrib/llvm-project/lldb/source/Interpreter/OptionValueSInt64.cpp @@ -8,7 +8,6 @@ #include "lldb/Interpreter/OptionValueSInt64.h" -#include "lldb/Host/StringConvert.h" #include "lldb/Utility/Stream.h" using namespace lldb; @@ -41,10 +40,9 @@ Status OptionValueSInt64::SetValueFromString(llvm::StringRef value_ref, case eVarSetOperationReplace: case eVarSetOperationAssign: { - bool success = false; - std::string value_str = value_ref.trim().str(); - int64_t value = StringConvert::ToSInt64(value_str.c_str(), 0, 0, &success); - if (success) { + llvm::StringRef value_trimmed = value_ref.trim(); + int64_t value; + if (llvm::to_integer(value_trimmed, value)) { if (value >= m_min_value && value <= m_max_value) { m_value_was_set = true; m_current_value = value; diff --git a/contrib/llvm-project/lldb/source/Interpreter/OptionValueUInt64.cpp b/contrib/llvm-project/lldb/source/Interpreter/OptionValueUInt64.cpp index a2751a4d02eb..1999c63d11af 100644 --- a/contrib/llvm-project/lldb/source/Interpreter/OptionValueUInt64.cpp +++ b/contrib/llvm-project/lldb/source/Interpreter/OptionValueUInt64.cpp @@ -8,7 +8,6 @@ #include "lldb/Interpreter/OptionValueUInt64.h" -#include "lldb/Host/StringConvert.h" #include "lldb/Utility/Stream.h" using namespace lldb; @@ -45,16 +44,15 @@ Status OptionValueUInt64::SetValueFromString(llvm::StringRef value_ref, case eVarSetOperationReplace: case eVarSetOperationAssign: { - bool success = false; - std::string value_str = value_ref.trim().str(); - uint64_t value = StringConvert::ToUInt64(value_str.c_str(), 0, 0, &success); - if (success) { + llvm::StringRef value_trimmed = value_ref.trim(); + uint64_t value; + if (llvm::to_integer(value_trimmed, value)) { m_value_was_set = true; m_current_value = value; NotifyValueChanged(); } else { error.SetErrorStringWithFormat("invalid uint64_t string value: '%s'", - value_str.c_str()); + value_ref.str().c_str()); } } break; diff --git a/contrib/llvm-project/lldb/source/Interpreter/Property.cpp b/contrib/llvm-project/lldb/source/Interpreter/Property.cpp index 55400a2bc42d..fe3a8a31394b 100644 --- a/contrib/llvm-project/lldb/source/Interpreter/Property.cpp +++ b/contrib/llvm-project/lldb/source/Interpreter/Property.cpp @@ -9,7 +9,6 @@ #include "lldb/Interpreter/Property.h" #include "lldb/Core/UserSettingsController.h" -#include "lldb/Host/StringConvert.h" #include "lldb/Interpreter/CommandInterpreter.h" #include "lldb/Interpreter/OptionArgParser.h" #include "lldb/Interpreter/OptionValues.h" @@ -176,28 +175,32 @@ Property::Property(const PropertyDefinition &definition) std::make_shared<OptionValueRegex>(definition.default_cstr_value); break; - case OptionValue::eTypeSInt64: + case OptionValue::eTypeSInt64: { // "definition.default_uint_value" is the default integer value if // "definition.default_cstr_value" is NULL, otherwise interpret // "definition.default_cstr_value" as a string value that represents the // default value. + int64_t value = 0; + // FIXME: improve error handling for llvm::to_integer() + if (definition.default_cstr_value) + llvm::to_integer(definition.default_cstr_value, value); m_value_sp = std::make_shared<OptionValueSInt64>( - definition.default_cstr_value - ? StringConvert::ToSInt64(definition.default_cstr_value) - : definition.default_uint_value); + definition.default_cstr_value ? value : definition.default_uint_value); break; - - case OptionValue::eTypeUInt64: + } + case OptionValue::eTypeUInt64: { + uint64_t value = 0; + // FIXME: improve error handling for llvm::to_integer() + if (definition.default_cstr_value) + llvm::to_integer(definition.default_cstr_value, value); // "definition.default_uint_value" is the default unsigned integer value if // "definition.default_cstr_value" is NULL, otherwise interpret // "definition.default_cstr_value" as a string value that represents the // default value. m_value_sp = std::make_shared<OptionValueUInt64>( - definition.default_cstr_value - ? StringConvert::ToUInt64(definition.default_cstr_value) - : definition.default_uint_value); + definition.default_cstr_value ? value : definition.default_uint_value); break; - + } case OptionValue::eTypeUUID: // "definition.default_uint_value" is not used for a OptionValue::eTypeUUID // "definition.default_cstr_value" can contain a default UUID value @@ -224,13 +227,13 @@ Property::Property(const PropertyDefinition &definition) } } -Property::Property(ConstString name, ConstString desc, - bool is_global, const lldb::OptionValueSP &value_sp) +Property::Property(llvm::StringRef name, llvm::StringRef desc, bool is_global, + const lldb::OptionValueSP &value_sp) : m_name(name), m_description(desc), m_value_sp(value_sp), m_is_global(is_global) {} bool Property::DumpQualifiedName(Stream &strm) const { - if (m_name) { + if (!m_name.empty()) { if (m_value_sp->DumpQualifiedName(strm)) strm.PutChar('.'); strm << m_name; @@ -248,7 +251,7 @@ void Property::Dump(const ExecutionContext *exe_ctx, Stream &strm, if (dump_cmd && !transparent) strm << "settings set -f "; if (dump_desc || !transparent) { - if ((dump_mask & OptionValue::eDumpOptionName) && m_name) { + if ((dump_mask & OptionValue::eDumpOptionName) && !m_name.empty()) { DumpQualifiedName(strm); if (dump_mask & ~OptionValue::eDumpOptionName) strm.PutChar(' '); @@ -292,8 +295,8 @@ void Property::DumpDescription(CommandInterpreter &interpreter, Stream &strm, interpreter.OutputFormattedHelpText(strm, qualified_name.GetString(), "--", desc, output_width); } else { - interpreter.OutputFormattedHelpText(strm, m_name.GetStringRef(), "--", - desc, output_width); + interpreter.OutputFormattedHelpText(strm, m_name, "--", desc, + output_width); } } } diff --git a/contrib/llvm-project/lldb/source/Interpreter/ScriptInterpreter.cpp b/contrib/llvm-project/lldb/source/Interpreter/ScriptInterpreter.cpp index f26474836a68..fbdcbb8da868 100644 --- a/contrib/llvm-project/lldb/source/Interpreter/ScriptInterpreter.cpp +++ b/contrib/llvm-project/lldb/source/Interpreter/ScriptInterpreter.cpp @@ -46,6 +46,10 @@ void ScriptInterpreter::CollectDataForWatchpointCommandCallback( "This script interpreter does not support watchpoint callbacks."); } +StructuredData::DictionarySP ScriptInterpreter::GetInterpreterInfo() { + return nullptr; +} + bool ScriptInterpreter::LoadScriptingModule(const char *filename, const LoadScriptOptions &options, lldb_private::Status &error, @@ -83,6 +87,14 @@ ScriptInterpreter::GetStatusFromSBError(const lldb::SBError &error) const { return Status(); } +llvm::Optional<MemoryRegionInfo> +ScriptInterpreter::GetOpaqueTypeFromSBMemoryRegionInfo( + const lldb::SBMemoryRegionInfo &mem_region) const { + if (!mem_region.m_opaque_up) + return llvm::None; + return *mem_region.m_opaque_up.get(); +} + lldb::ScriptLanguage ScriptInterpreter::StringToLanguage(const llvm::StringRef &language) { if (language.equals_insensitive(LanguageToString(eScriptLanguageNone))) @@ -141,12 +153,12 @@ ScriptInterpreterIORedirect::Create(bool enable_io, Debugger &debugger, new ScriptInterpreterIORedirect(debugger, result)); auto nullin = FileSystem::Instance().Open(FileSpec(FileSystem::DEV_NULL), - File::eOpenOptionRead); + File::eOpenOptionReadOnly); if (!nullin) return nullin.takeError(); auto nullout = FileSystem::Instance().Open(FileSpec(FileSystem::DEV_NULL), - File::eOpenOptionWrite); + File::eOpenOptionWriteOnly); if (!nullout) return nullin.takeError(); diff --git a/contrib/llvm-project/lldb/source/Plugins/ABI/AArch64/ABIAArch64.cpp b/contrib/llvm-project/lldb/source/Plugins/ABI/AArch64/ABIAArch64.cpp index 505c7d416a82..2de9c346d387 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ABI/AArch64/ABIAArch64.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/ABI/AArch64/ABIAArch64.cpp @@ -15,6 +15,8 @@ #include "lldb/Core/PluginManager.h" #include "lldb/Target/Process.h" +#include <bitset> + LLDB_PLUGIN_DEFINE(ABIAArch64) void ABIAArch64::Initialize() { @@ -58,12 +60,13 @@ std::string ABIAArch64::GetMCName(std::string reg) { MapRegisterName(reg, "x30", "lr"); return reg; } + uint32_t ABIAArch64::GetGenericNum(llvm::StringRef name) { return llvm::StringSwitch<uint32_t>(name) .Case("pc", LLDB_REGNUM_GENERIC_PC) - .Case("lr", LLDB_REGNUM_GENERIC_RA) - .Case("sp", LLDB_REGNUM_GENERIC_SP) - .Case("fp", LLDB_REGNUM_GENERIC_FP) + .Cases("lr", "x30", LLDB_REGNUM_GENERIC_RA) + .Cases("sp", "x31", LLDB_REGNUM_GENERIC_SP) + .Cases("fp", "x29", LLDB_REGNUM_GENERIC_FP) .Case("cpsr", LLDB_REGNUM_GENERIC_FLAGS) .Case("x0", LLDB_REGNUM_GENERIC_ARG1) .Case("x1", LLDB_REGNUM_GENERIC_ARG2) @@ -75,3 +78,76 @@ uint32_t ABIAArch64::GetGenericNum(llvm::StringRef name) { .Case("x7", LLDB_REGNUM_GENERIC_ARG8) .Default(LLDB_INVALID_REGNUM); } + +static void addPartialRegisters( + std::vector<lldb_private::DynamicRegisterInfo::Register> ®s, + llvm::ArrayRef<llvm::Optional<uint32_t>> full_reg_indices, + uint32_t full_reg_size, const char *partial_reg_format, + uint32_t partial_reg_size, lldb::Encoding encoding, lldb::Format format) { + for (auto it : llvm::enumerate(full_reg_indices)) { + llvm::Optional<uint32_t> full_reg_index = it.value(); + if (!full_reg_index || + regs[full_reg_index.getValue()].byte_size != full_reg_size) + return; + + lldb_private::DynamicRegisterInfo::Register partial_reg{ + lldb_private::ConstString( + llvm::formatv(partial_reg_format, it.index()).str()), + lldb_private::ConstString(), + lldb_private::ConstString("supplementary registers"), + partial_reg_size, + LLDB_INVALID_INDEX32, + encoding, + format, + LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, + {full_reg_index.getValue()}, + {}}; + addSupplementaryRegister(regs, partial_reg); + } +} + +void ABIAArch64::AugmentRegisterInfo( + std::vector<lldb_private::DynamicRegisterInfo::Register> ®s) { + lldb_private::MCBasedABI::AugmentRegisterInfo(regs); + + lldb_private::ConstString sp_string{"sp"}; + + std::array<llvm::Optional<uint32_t>, 32> x_regs; + std::array<llvm::Optional<uint32_t>, 32> v_regs; + + for (auto it : llvm::enumerate(regs)) { + lldb_private::DynamicRegisterInfo::Register &info = it.value(); + // GDB sends x31 as "sp". Add the "x31" alt_name for convenience. + if (info.name == sp_string && !info.alt_name) + info.alt_name.SetCString("x31"); + + unsigned int reg_num; + auto get_reg = [&info, ®_num](const char *prefix) { + llvm::StringRef reg_name = info.name.GetStringRef(); + llvm::StringRef alt_name = info.alt_name.GetStringRef(); + return (reg_name.consume_front(prefix) && + llvm::to_integer(reg_name, reg_num, 10) && reg_num < 32) || + (alt_name.consume_front(prefix) && + llvm::to_integer(alt_name, reg_num, 10) && reg_num < 32); + }; + + if (get_reg("x")) + x_regs[reg_num] = it.index(); + else if (get_reg("v")) + v_regs[reg_num] = it.index(); + // if we have at least one subregister, abort + else if (get_reg("w") || get_reg("s") || get_reg("d")) + return; + } + + // Create aliases for partial registers: wN for xN, and sN/dN for vN. + addPartialRegisters(regs, x_regs, 8, "w{0}", 4, lldb::eEncodingUint, + lldb::eFormatHex); + addPartialRegisters(regs, v_regs, 16, "s{0}", 4, lldb::eEncodingIEEE754, + lldb::eFormatFloat); + addPartialRegisters(regs, v_regs, 16, "d{0}", 8, lldb::eEncodingIEEE754, + lldb::eFormatFloat); +} diff --git a/contrib/llvm-project/lldb/source/Plugins/ABI/AArch64/ABIAArch64.h b/contrib/llvm-project/lldb/source/Plugins/ABI/AArch64/ABIAArch64.h index 41bbf5cfdeb9..e771f69d7dbc 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ABI/AArch64/ABIAArch64.h +++ b/contrib/llvm-project/lldb/source/Plugins/ABI/AArch64/ABIAArch64.h @@ -11,7 +11,7 @@ #include "lldb/Target/ABI.h" -class ABIAArch64: public lldb_private::MCBasedABI { +class ABIAArch64 : public lldb_private::MCBasedABI { public: static void Initialize(); static void Terminate(); @@ -31,6 +31,9 @@ protected: uint32_t GetGenericNum(llvm::StringRef name) override; + void AugmentRegisterInfo( + std::vector<lldb_private::DynamicRegisterInfo::Register> ®s) override; + using lldb_private::MCBasedABI::MCBasedABI; }; #endif diff --git a/contrib/llvm-project/lldb/source/Plugins/ABI/AArch64/ABIMacOSX_arm64.cpp b/contrib/llvm-project/lldb/source/Plugins/ABI/AArch64/ABIMacOSX_arm64.cpp index 348a081cfe17..ccfbeec3d589 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ABI/AArch64/ABIMacOSX_arm64.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/ABI/AArch64/ABIMacOSX_arm64.cpp @@ -402,7 +402,7 @@ bool ABIMacOSX_arm64::CreateDefaultUnwindPlan(UnwindPlan &unwind_plan) { // volatile (and specifically only the lower 8 bytes of these regs), the rest // of the fp/SIMD registers are volatile. // -// v. https://github.com/ARM-software/abi-aa/blob/master/aapcs64/ +// v. https://github.com/ARM-software/abi-aa/blob/main/aapcs64/ // We treat x29 as callee preserved also, else the unwinder won't try to // retrieve fp saves. @@ -828,12 +828,3 @@ void ABIMacOSX_arm64::Initialize() { void ABIMacOSX_arm64::Terminate() { PluginManager::UnregisterPlugin(CreateInstance); } - -// PluginInterface protocol - -ConstString ABIMacOSX_arm64::GetPluginNameStatic() { - static ConstString g_plugin_name("ABIMacOSX_arm64"); - return g_plugin_name; -} - -uint32_t ABIMacOSX_arm64::GetPluginVersion() { return 1; } diff --git a/contrib/llvm-project/lldb/source/Plugins/ABI/AArch64/ABIMacOSX_arm64.h b/contrib/llvm-project/lldb/source/Plugins/ABI/AArch64/ABIMacOSX_arm64.h index dc3ab35115fd..1a5bc7f67573 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ABI/AArch64/ABIMacOSX_arm64.h +++ b/contrib/llvm-project/lldb/source/Plugins/ABI/AArch64/ABIMacOSX_arm64.h @@ -74,13 +74,9 @@ public: // PluginInterface protocol - static lldb_private::ConstString GetPluginNameStatic(); + static llvm::StringRef GetPluginNameStatic() { return "ABIMacOSX_arm64"; } - lldb_private::ConstString GetPluginName() override { - return GetPluginNameStatic(); - } - - uint32_t GetPluginVersion() override; + llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); } lldb_private::Status SetReturnValueObject(lldb::StackFrameSP &frame_sp, diff --git a/contrib/llvm-project/lldb/source/Plugins/ABI/AArch64/ABISysV_arm64.cpp b/contrib/llvm-project/lldb/source/Plugins/ABI/AArch64/ABISysV_arm64.cpp index 16fb38e107c3..95924159e9f0 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ABI/AArch64/ABISysV_arm64.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/ABI/AArch64/ABISysV_arm64.cpp @@ -845,14 +845,3 @@ void ABISysV_arm64::Initialize() { void ABISysV_arm64::Terminate() { PluginManager::UnregisterPlugin(CreateInstance); } - -lldb_private::ConstString ABISysV_arm64::GetPluginNameStatic() { - static ConstString g_name("SysV-arm64"); - return g_name; -} - -// PluginInterface protocol - -ConstString ABISysV_arm64::GetPluginName() { return GetPluginNameStatic(); } - -uint32_t ABISysV_arm64::GetPluginVersion() { return 1; } diff --git a/contrib/llvm-project/lldb/source/Plugins/ABI/AArch64/ABISysV_arm64.h b/contrib/llvm-project/lldb/source/Plugins/ABI/AArch64/ABISysV_arm64.h index 3428a7ad9418..b3d4cba795f0 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ABI/AArch64/ABISysV_arm64.h +++ b/contrib/llvm-project/lldb/source/Plugins/ABI/AArch64/ABISysV_arm64.h @@ -77,13 +77,11 @@ public: static lldb::ABISP CreateInstance(lldb::ProcessSP process_sp, const lldb_private::ArchSpec &arch); - static lldb_private::ConstString GetPluginNameStatic(); + static llvm::StringRef GetPluginNameStatic() { return "SysV-arm64"; } // PluginInterface protocol - lldb_private::ConstString GetPluginName() override; - - uint32_t GetPluginVersion() override; + llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); } lldb::addr_t FixCodeAddress(lldb::addr_t pc) override; lldb::addr_t FixDataAddress(lldb::addr_t pc) override; diff --git a/contrib/llvm-project/lldb/source/Plugins/ABI/ARC/ABISysV_arc.cpp b/contrib/llvm-project/lldb/source/Plugins/ABI/ARC/ABISysV_arc.cpp index 60cdbc534113..3620be6f274d 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ABI/ARC/ABISysV_arc.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/ABI/ARC/ABISysV_arc.cpp @@ -46,7 +46,7 @@ DEFINE_REG_NAME(dwarf_num), DEFINE_REG_NAME_STR(str_name), \ 0, 0, eEncodingInvalid, eFormatDefault, \ { dwarf_num, dwarf_num, generic_num, LLDB_INVALID_REGNUM, dwarf_num }, \ - nullptr, nullptr, nullptr, 0 \ + nullptr, nullptr \ } #define DEFINE_REGISTER_STUB(dwarf_num, str_name) \ @@ -167,15 +167,15 @@ ABISP ABISysV_arc::CreateInstance(ProcessSP process_sp, const ArchSpec &arch) { ABISP(); } -namespace { -const size_t word_size = 4U; -const size_t reg_size = word_size; +static const size_t word_size = 4U; +static const size_t reg_size = word_size; -inline size_t AugmentArgSize(size_t size_in_bytes) { +static inline size_t AugmentArgSize(size_t size_in_bytes) { return llvm::alignTo(size_in_bytes, word_size); } -size_t TotalArgsSizeInWords(const llvm::ArrayRef<ABI::CallArgument> &args) { +static size_t +TotalArgsSizeInWords(const llvm::ArrayRef<ABI::CallArgument> &args) { size_t total_size = 0; for (const auto &arg : args) total_size += @@ -185,7 +185,6 @@ size_t TotalArgsSizeInWords(const llvm::ArrayRef<ABI::CallArgument> &args) { return total_size; } -} // namespace bool ABISysV_arc::PrepareTrivialCall(Thread &thread, addr_t sp, addr_t func_addr, addr_t return_addr, @@ -372,9 +371,8 @@ Status ABISysV_arc::SetReturnValueObject(StackFrameSP &frame_sp, return result; } -namespace { template <typename T> -void SetInteger(Scalar &scalar, uint64_t raw_value, bool is_signed) { +static void SetInteger(Scalar &scalar, uint64_t raw_value, bool is_signed) { raw_value &= std::numeric_limits<T>::max(); if (is_signed) scalar = static_cast<typename std::make_signed<T>::type>(raw_value); @@ -382,8 +380,8 @@ void SetInteger(Scalar &scalar, uint64_t raw_value, bool is_signed) { scalar = static_cast<T>(raw_value); } -bool SetSizedInteger(Scalar &scalar, uint64_t raw_value, uint8_t size_in_bytes, - bool is_signed) { +static bool SetSizedInteger(Scalar &scalar, uint64_t raw_value, + uint8_t size_in_bytes, bool is_signed) { switch (size_in_bytes) { default: return false; @@ -408,7 +406,8 @@ bool SetSizedInteger(Scalar &scalar, uint64_t raw_value, uint8_t size_in_bytes, return true; } -bool SetSizedFloat(Scalar &scalar, uint64_t raw_value, uint8_t size_in_bytes) { +static bool SetSizedFloat(Scalar &scalar, uint64_t raw_value, + uint8_t size_in_bytes) { switch (size_in_bytes) { default: return false; @@ -425,7 +424,8 @@ bool SetSizedFloat(Scalar &scalar, uint64_t raw_value, uint8_t size_in_bytes) { return true; } -uint64_t ReadRawValue(const RegisterContextSP ®_ctx, uint8_t size_in_bytes) { +static uint64_t ReadRawValue(const RegisterContextSP ®_ctx, + uint8_t size_in_bytes) { auto reg_info_r0 = reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1); @@ -441,7 +441,6 @@ uint64_t ReadRawValue(const RegisterContextSP ®_ctx, uint8_t size_in_bytes) { return raw_value; } -} // namespace ValueObjectSP ABISysV_arc::GetReturnValueObjectSimple(Thread &thread, @@ -600,18 +599,3 @@ void ABISysV_arc::Initialize() { void ABISysV_arc::Terminate() { PluginManager::UnregisterPlugin(CreateInstance); } - -ConstString ABISysV_arc::GetPluginNameStatic() { - static ConstString g_name("sysv-arc"); - return g_name; -} - -//------------------------------------------------------------------ -// PluginInterface protocol -//------------------------------------------------------------------ - -ConstString ABISysV_arc::GetPluginName() { - return GetPluginNameStatic(); -} - -uint32_t ABISysV_arc::GetPluginVersion() { return 1; } diff --git a/contrib/llvm-project/lldb/source/Plugins/ABI/ARC/ABISysV_arc.h b/contrib/llvm-project/lldb/source/Plugins/ABI/ARC/ABISysV_arc.h index 3fbe64b4b45b..9bf75dfe6add 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ABI/ARC/ABISysV_arc.h +++ b/contrib/llvm-project/lldb/source/Plugins/ABI/ARC/ABISysV_arc.h @@ -1,4 +1,4 @@ -//===-- ArchitectureArc.h ---------------------------------------*- C++ -*-===// +//===-- ABISysV_arc.h -------------------------------------------*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -80,15 +80,13 @@ public: static lldb::ABISP CreateInstance(lldb::ProcessSP process_sp, const lldb_private::ArchSpec &arch); - static lldb_private::ConstString GetPluginNameStatic(); + static llvm::StringRef GetPluginNameStatic() { return "sysv-arc"; } //------------------------------------------------------------------ // PluginInterface protocol //------------------------------------------------------------------ - lldb_private::ConstString GetPluginName() override; - - uint32_t GetPluginVersion() override; + llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); } private: lldb::ValueObjectSP diff --git a/contrib/llvm-project/lldb/source/Plugins/ABI/ARM/ABIMacOSX_arm.cpp b/contrib/llvm-project/lldb/source/Plugins/ABI/ARM/ABIMacOSX_arm.cpp index e429f3ee0cc4..a8d1cbc675e3 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ABI/ARM/ABIMacOSX_arm.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/ABI/ARM/ABIMacOSX_arm.cpp @@ -42,7 +42,7 @@ static const RegisterInfo g_register_infos[] = { // ======================= =================== =========================== // ======================= ====================== {"r0", - "arg1", + nullptr, 4, 0, eEncodingUint, @@ -51,10 +51,9 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"r1", - "arg2", + nullptr, 4, 0, eEncodingUint, @@ -63,10 +62,9 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"r2", - "arg3", + nullptr, 4, 0, eEncodingUint, @@ -75,10 +73,9 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"r3", - "arg4", + nullptr, 4, 0, eEncodingUint, @@ -87,8 +84,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"r4", nullptr, 4, @@ -99,8 +95,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"r5", nullptr, 4, @@ -111,8 +106,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"r6", nullptr, 4, @@ -123,8 +117,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"r7", nullptr, 4, @@ -135,8 +128,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"r8", nullptr, 4, @@ -147,8 +139,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"r9", nullptr, 4, @@ -159,8 +150,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"r10", nullptr, 4, @@ -171,8 +161,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"r11", nullptr, 4, @@ -183,8 +172,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"r12", nullptr, 4, @@ -195,8 +183,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"sp", "r13", 4, @@ -207,8 +194,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"lr", "r14", 4, @@ -219,8 +205,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"pc", "r15", 4, @@ -231,8 +216,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"cpsr", "psr", 4, @@ -243,8 +227,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"s0", nullptr, 4, @@ -255,8 +238,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"s1", nullptr, 4, @@ -267,8 +249,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"s2", nullptr, 4, @@ -279,8 +260,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"s3", nullptr, 4, @@ -291,8 +271,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"s4", nullptr, 4, @@ -303,8 +282,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"s5", nullptr, 4, @@ -315,8 +293,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"s6", nullptr, 4, @@ -327,8 +304,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"s7", nullptr, 4, @@ -339,8 +315,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"s8", nullptr, 4, @@ -351,8 +326,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"s9", nullptr, 4, @@ -363,8 +337,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"s10", nullptr, 4, @@ -375,8 +348,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"s11", nullptr, 4, @@ -387,8 +359,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"s12", nullptr, 4, @@ -399,8 +370,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"s13", nullptr, 4, @@ -411,8 +381,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"s14", nullptr, 4, @@ -423,8 +392,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"s15", nullptr, 4, @@ -435,8 +403,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"s16", nullptr, 4, @@ -447,8 +414,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"s17", nullptr, 4, @@ -459,8 +425,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"s18", nullptr, 4, @@ -471,8 +436,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"s19", nullptr, 4, @@ -483,8 +447,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"s20", nullptr, 4, @@ -495,8 +458,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"s21", nullptr, 4, @@ -507,8 +469,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"s22", nullptr, 4, @@ -519,8 +480,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"s23", nullptr, 4, @@ -531,8 +491,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"s24", nullptr, 4, @@ -543,8 +502,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"s25", nullptr, 4, @@ -555,8 +513,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"s26", nullptr, 4, @@ -567,8 +524,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"s27", nullptr, 4, @@ -579,8 +535,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"s28", nullptr, 4, @@ -591,8 +546,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"s29", nullptr, 4, @@ -603,8 +557,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"s30", nullptr, 4, @@ -615,8 +568,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"s31", nullptr, 4, @@ -627,8 +579,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"fpscr", nullptr, 4, @@ -639,8 +590,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"d0", nullptr, 8, @@ -651,8 +601,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"d1", nullptr, 8, @@ -663,8 +612,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"d2", nullptr, 8, @@ -675,8 +623,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"d3", nullptr, 8, @@ -687,8 +634,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"d4", nullptr, 8, @@ -699,8 +645,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"d5", nullptr, 8, @@ -711,8 +656,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"d6", nullptr, 8, @@ -723,8 +667,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"d7", nullptr, 8, @@ -735,8 +678,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"d8", nullptr, 8, @@ -747,8 +689,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"d9", nullptr, 8, @@ -759,8 +700,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"d10", nullptr, 8, @@ -771,8 +711,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"d11", nullptr, 8, @@ -783,8 +722,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"d12", nullptr, 8, @@ -795,8 +733,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"d13", nullptr, 8, @@ -807,8 +744,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"d14", nullptr, 8, @@ -819,8 +755,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"d15", nullptr, 8, @@ -831,8 +766,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"d16", nullptr, 8, @@ -843,8 +777,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"d17", nullptr, 8, @@ -855,8 +788,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"d18", nullptr, 8, @@ -867,8 +799,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"d19", nullptr, 8, @@ -879,8 +810,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"d20", nullptr, 8, @@ -891,8 +821,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"d21", nullptr, 8, @@ -903,8 +832,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"d22", nullptr, 8, @@ -915,8 +843,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"d23", nullptr, 8, @@ -927,8 +854,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"d24", nullptr, 8, @@ -939,8 +865,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"d25", nullptr, 8, @@ -951,8 +876,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"d26", nullptr, 8, @@ -963,8 +887,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"d27", nullptr, 8, @@ -975,8 +898,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"d28", nullptr, 8, @@ -987,8 +909,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"d29", nullptr, 8, @@ -999,8 +920,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"d30", nullptr, 8, @@ -1011,8 +931,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"d31", nullptr, 8, @@ -1023,8 +942,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"r8_usr", nullptr, 4, @@ -1035,8 +953,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"r9_usr", nullptr, 4, @@ -1047,8 +964,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"r10_usr", nullptr, 4, @@ -1059,8 +975,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"r11_usr", nullptr, 4, @@ -1071,8 +986,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"r12_usr", nullptr, 4, @@ -1083,8 +997,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"r13_usr", "sp_usr", 4, @@ -1095,8 +1008,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"r14_usr", "lr_usr", 4, @@ -1107,8 +1019,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"r8_fiq", nullptr, 4, @@ -1119,8 +1030,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"r9_fiq", nullptr, 4, @@ -1131,8 +1041,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"r10_fiq", nullptr, 4, @@ -1143,8 +1052,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"r11_fiq", nullptr, 4, @@ -1155,8 +1063,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"r12_fiq", nullptr, 4, @@ -1167,8 +1074,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"r13_fiq", "sp_fiq", 4, @@ -1179,8 +1085,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"r14_fiq", "lr_fiq", 4, @@ -1191,8 +1096,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"r13_irq", "sp_irq", 4, @@ -1203,8 +1107,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"r14_irq", "lr_irq", 4, @@ -1215,8 +1118,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"r13_abt", "sp_abt", 4, @@ -1227,8 +1129,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"r14_abt", "lr_abt", 4, @@ -1239,8 +1140,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"r13_und", "sp_und", 4, @@ -1251,8 +1151,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"r14_und", "lr_und", 4, @@ -1263,8 +1162,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"r13_svc", "sp_svc", 4, @@ -1275,8 +1173,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"r14_svc", "lr_svc", 4, @@ -1287,8 +1184,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}}; + }}; static const uint32_t k_num_register_infos = llvm::array_lengthof(g_register_infos); @@ -2025,16 +1921,3 @@ void ABIMacOSX_arm::Initialize() { void ABIMacOSX_arm::Terminate() { PluginManager::UnregisterPlugin(CreateInstance); } - -lldb_private::ConstString ABIMacOSX_arm::GetPluginNameStatic() { - static ConstString g_name("macosx-arm"); - return g_name; -} - -// PluginInterface protocol - -lldb_private::ConstString ABIMacOSX_arm::GetPluginName() { - return GetPluginNameStatic(); -} - -uint32_t ABIMacOSX_arm::GetPluginVersion() { return 1; } diff --git a/contrib/llvm-project/lldb/source/Plugins/ABI/ARM/ABIMacOSX_arm.h b/contrib/llvm-project/lldb/source/Plugins/ABI/ARM/ABIMacOSX_arm.h index e0fa349eea73..a77af75e57b8 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ABI/ARM/ABIMacOSX_arm.h +++ b/contrib/llvm-project/lldb/source/Plugins/ABI/ARM/ABIMacOSX_arm.h @@ -71,13 +71,11 @@ public: static lldb::ABISP CreateInstance(lldb::ProcessSP process_sp, const lldb_private::ArchSpec &arch); - static lldb_private::ConstString GetPluginNameStatic(); + static llvm::StringRef GetPluginNameStatic() { return "macosx-arm"; } // PluginInterface protocol - lldb_private::ConstString GetPluginName() override; - - uint32_t GetPluginVersion() override; + llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); } protected: lldb::ValueObjectSP diff --git a/contrib/llvm-project/lldb/source/Plugins/ABI/ARM/ABISysV_arm.cpp b/contrib/llvm-project/lldb/source/Plugins/ABI/ARM/ABISysV_arm.cpp index 3e544e0483a7..9ed042df4e50 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ABI/ARM/ABISysV_arm.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/ABI/ARM/ABISysV_arm.cpp @@ -45,7 +45,7 @@ static const RegisterInfo g_register_infos[] = { // ======================= ====================== ========== // =============== {"r0", - "arg1", + nullptr, 4, 0, eEncodingUint, @@ -54,10 +54,9 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"r1", - "arg2", + nullptr, 4, 0, eEncodingUint, @@ -66,10 +65,9 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"r2", - "arg3", + nullptr, 4, 0, eEncodingUint, @@ -78,10 +76,9 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"r3", - "arg4", + nullptr, 4, 0, eEncodingUint, @@ -90,8 +87,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"r4", nullptr, 4, @@ -102,8 +98,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"r5", nullptr, 4, @@ -114,8 +109,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"r6", nullptr, 4, @@ -126,8 +120,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"r7", nullptr, 4, @@ -138,8 +131,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"r8", nullptr, 4, @@ -150,8 +142,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"r9", nullptr, 4, @@ -162,8 +153,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"r10", nullptr, 4, @@ -174,8 +164,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"r11", nullptr, 4, @@ -186,8 +175,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"r12", nullptr, 4, @@ -198,8 +186,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"sp", "r13", 4, @@ -210,8 +197,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"lr", "r14", 4, @@ -222,8 +208,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"pc", "r15", 4, @@ -234,8 +219,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"cpsr", "psr", 4, @@ -246,8 +230,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"s0", nullptr, 4, @@ -258,8 +241,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"s1", nullptr, 4, @@ -270,8 +252,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"s2", nullptr, 4, @@ -282,8 +263,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"s3", nullptr, 4, @@ -294,8 +274,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"s4", nullptr, 4, @@ -306,8 +285,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"s5", nullptr, 4, @@ -318,8 +296,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"s6", nullptr, 4, @@ -330,8 +307,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"s7", nullptr, 4, @@ -342,8 +318,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"s8", nullptr, 4, @@ -354,8 +329,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"s9", nullptr, 4, @@ -366,8 +340,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"s10", nullptr, 4, @@ -378,8 +351,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"s11", nullptr, 4, @@ -390,8 +362,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"s12", nullptr, 4, @@ -402,8 +373,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"s13", nullptr, 4, @@ -414,8 +384,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"s14", nullptr, 4, @@ -426,8 +395,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"s15", nullptr, 4, @@ -438,8 +406,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"s16", nullptr, 4, @@ -450,8 +417,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"s17", nullptr, 4, @@ -462,8 +428,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"s18", nullptr, 4, @@ -474,8 +439,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"s19", nullptr, 4, @@ -486,8 +450,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"s20", nullptr, 4, @@ -498,8 +461,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"s21", nullptr, 4, @@ -510,8 +472,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"s22", nullptr, 4, @@ -522,8 +483,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"s23", nullptr, 4, @@ -534,8 +494,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"s24", nullptr, 4, @@ -546,8 +505,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"s25", nullptr, 4, @@ -558,8 +516,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"s26", nullptr, 4, @@ -570,8 +527,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"s27", nullptr, 4, @@ -582,8 +538,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"s28", nullptr, 4, @@ -594,8 +549,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"s29", nullptr, 4, @@ -606,8 +560,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"s30", nullptr, 4, @@ -618,8 +571,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"s31", nullptr, 4, @@ -630,8 +582,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"fpscr", nullptr, 4, @@ -642,8 +593,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"d0", nullptr, 8, @@ -654,8 +604,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"d1", nullptr, 8, @@ -666,8 +615,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"d2", nullptr, 8, @@ -678,8 +626,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"d3", nullptr, 8, @@ -690,8 +637,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"d4", nullptr, 8, @@ -702,8 +648,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"d5", nullptr, 8, @@ -714,8 +659,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"d6", nullptr, 8, @@ -726,8 +670,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"d7", nullptr, 8, @@ -738,8 +681,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"d8", nullptr, 8, @@ -750,8 +692,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"d9", nullptr, 8, @@ -762,8 +703,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"d10", nullptr, 8, @@ -774,8 +714,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"d11", nullptr, 8, @@ -786,8 +725,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"d12", nullptr, 8, @@ -798,8 +736,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"d13", nullptr, 8, @@ -810,8 +747,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"d14", nullptr, 8, @@ -822,8 +758,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"d15", nullptr, 8, @@ -834,8 +769,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"d16", nullptr, 8, @@ -846,8 +780,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"d17", nullptr, 8, @@ -858,8 +791,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"d18", nullptr, 8, @@ -870,8 +802,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"d19", nullptr, 8, @@ -882,8 +813,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"d20", nullptr, 8, @@ -894,8 +824,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"d21", nullptr, 8, @@ -906,8 +835,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"d22", nullptr, 8, @@ -918,8 +846,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"d23", nullptr, 8, @@ -930,8 +857,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"d24", nullptr, 8, @@ -942,8 +868,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"d25", nullptr, 8, @@ -954,8 +879,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"d26", nullptr, 8, @@ -966,8 +890,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"d27", nullptr, 8, @@ -978,8 +901,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"d28", nullptr, 8, @@ -990,8 +912,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"d29", nullptr, 8, @@ -1002,8 +923,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"d30", nullptr, 8, @@ -1014,8 +934,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"d31", nullptr, 8, @@ -1026,8 +945,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"r8_usr", nullptr, 4, @@ -1038,8 +956,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"r9_usr", nullptr, 4, @@ -1050,8 +967,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"r10_usr", nullptr, 4, @@ -1062,8 +978,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"r11_usr", nullptr, 4, @@ -1074,8 +989,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"r12_usr", nullptr, 4, @@ -1086,8 +1000,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"r13_usr", "sp_usr", 4, @@ -1098,8 +1011,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"r14_usr", "lr_usr", 4, @@ -1110,8 +1022,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"r8_fiq", nullptr, 4, @@ -1122,8 +1033,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"r9_fiq", nullptr, 4, @@ -1134,8 +1044,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"r10_fiq", nullptr, 4, @@ -1146,8 +1055,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"r11_fiq", nullptr, 4, @@ -1158,8 +1066,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"r12_fiq", nullptr, 4, @@ -1170,8 +1077,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"r13_fiq", "sp_fiq", 4, @@ -1182,8 +1088,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"r14_fiq", "lr_fiq", 4, @@ -1194,8 +1099,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"r13_irq", "sp_irq", 4, @@ -1206,8 +1110,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"r14_irq", "lr_irq", 4, @@ -1218,8 +1121,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"r13_abt", "sp_abt", 4, @@ -1230,8 +1132,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"r14_abt", "lr_abt", 4, @@ -1242,8 +1143,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"r13_und", "sp_und", 4, @@ -1254,8 +1154,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"r14_und", "lr_und", 4, @@ -1266,8 +1165,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"r13_svc", "sp_svc", 4, @@ -1278,8 +1176,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"r14_svc", "lr_svc", 4, @@ -1290,8 +1187,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}}; + }}; static const uint32_t k_num_register_infos = llvm::array_lengthof(g_register_infos); @@ -2131,16 +2027,3 @@ void ABISysV_arm::Initialize() { void ABISysV_arm::Terminate() { PluginManager::UnregisterPlugin(CreateInstance); } - -lldb_private::ConstString ABISysV_arm::GetPluginNameStatic() { - static ConstString g_name("SysV-arm"); - return g_name; -} - -// PluginInterface protocol - -lldb_private::ConstString ABISysV_arm::GetPluginName() { - return GetPluginNameStatic(); -} - -uint32_t ABISysV_arm::GetPluginVersion() { return 1; } diff --git a/contrib/llvm-project/lldb/source/Plugins/ABI/ARM/ABISysV_arm.h b/contrib/llvm-project/lldb/source/Plugins/ABI/ARM/ABISysV_arm.h index f28f75ce4fe5..ce67b367d18f 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ABI/ARM/ABISysV_arm.h +++ b/contrib/llvm-project/lldb/source/Plugins/ABI/ARM/ABISysV_arm.h @@ -71,13 +71,11 @@ public: static lldb::ABISP CreateInstance(lldb::ProcessSP process_sp, const lldb_private::ArchSpec &arch); - static lldb_private::ConstString GetPluginNameStatic(); + static llvm::StringRef GetPluginNameStatic() { return "SysV-arm"; } // PluginInterface protocol - lldb_private::ConstString GetPluginName() override; - - uint32_t GetPluginVersion() override; + llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); } protected: lldb::ValueObjectSP diff --git a/contrib/llvm-project/lldb/source/Plugins/ABI/Hexagon/ABISysV_hexagon.cpp b/contrib/llvm-project/lldb/source/Plugins/ABI/Hexagon/ABISysV_hexagon.cpp index 6794f7d07210..d47bca48ae09 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ABI/Hexagon/ABISysV_hexagon.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/ABI/Hexagon/ABISysV_hexagon.cpp @@ -45,8 +45,7 @@ static const RegisterInfo g_register_infos[] = { {0, 0, LLDB_INVALID_REGNUM, 0, 0}, nullptr, nullptr, - nullptr, - 0}, + }, {"r01", "", 4, @@ -56,8 +55,7 @@ static const RegisterInfo g_register_infos[] = { {1, 1, LLDB_INVALID_REGNUM, 1, 1}, nullptr, nullptr, - nullptr, - 0}, + }, {"r02", "", 4, @@ -67,8 +65,7 @@ static const RegisterInfo g_register_infos[] = { {2, 2, LLDB_INVALID_REGNUM, 2, 2}, nullptr, nullptr, - nullptr, - 0}, + }, {"r03", "", 4, @@ -78,8 +75,7 @@ static const RegisterInfo g_register_infos[] = { {3, 3, LLDB_INVALID_REGNUM, 3, 3}, nullptr, nullptr, - nullptr, - 0}, + }, {"r04", "", 4, @@ -89,8 +85,7 @@ static const RegisterInfo g_register_infos[] = { {4, 4, LLDB_INVALID_REGNUM, 4, 4}, nullptr, nullptr, - nullptr, - 0}, + }, {"r05", "", 4, @@ -100,8 +95,7 @@ static const RegisterInfo g_register_infos[] = { {5, 5, LLDB_INVALID_REGNUM, 5, 5}, nullptr, nullptr, - nullptr, - 0}, + }, {"r06", "", 4, @@ -111,8 +105,7 @@ static const RegisterInfo g_register_infos[] = { {6, 6, LLDB_INVALID_REGNUM, 6, 6}, nullptr, nullptr, - nullptr, - 0}, + }, {"r07", "", 4, @@ -122,8 +115,7 @@ static const RegisterInfo g_register_infos[] = { {7, 7, LLDB_INVALID_REGNUM, 7, 7}, nullptr, nullptr, - nullptr, - 0}, + }, {"r08", "", 4, @@ -133,8 +125,7 @@ static const RegisterInfo g_register_infos[] = { {8, 8, LLDB_INVALID_REGNUM, 8, 8}, nullptr, nullptr, - nullptr, - 0}, + }, {"r09", "", 4, @@ -144,8 +135,7 @@ static const RegisterInfo g_register_infos[] = { {9, 9, LLDB_INVALID_REGNUM, 9, 9}, nullptr, nullptr, - nullptr, - 0}, + }, {"r10", "", 4, @@ -155,8 +145,7 @@ static const RegisterInfo g_register_infos[] = { {10, 10, LLDB_INVALID_REGNUM, 10, 10}, nullptr, nullptr, - nullptr, - 0}, + }, {"r11", "", 4, @@ -166,8 +155,7 @@ static const RegisterInfo g_register_infos[] = { {11, 11, LLDB_INVALID_REGNUM, 11, 11}, nullptr, nullptr, - nullptr, - 0}, + }, {"r12", "", 4, @@ -177,8 +165,7 @@ static const RegisterInfo g_register_infos[] = { {12, 12, LLDB_INVALID_REGNUM, 12, 12}, nullptr, nullptr, - nullptr, - 0}, + }, {"r13", "", 4, @@ -188,8 +175,7 @@ static const RegisterInfo g_register_infos[] = { {13, 13, LLDB_INVALID_REGNUM, 13, 13}, nullptr, nullptr, - nullptr, - 0}, + }, {"r14", "", 4, @@ -199,8 +185,7 @@ static const RegisterInfo g_register_infos[] = { {14, 14, LLDB_INVALID_REGNUM, 14, 14}, nullptr, nullptr, - nullptr, - 0}, + }, {"r15", "", 4, @@ -210,8 +195,7 @@ static const RegisterInfo g_register_infos[] = { {15, 15, LLDB_INVALID_REGNUM, 15, 15}, nullptr, nullptr, - nullptr, - 0}, + }, {"r16", "", 4, @@ -221,8 +205,7 @@ static const RegisterInfo g_register_infos[] = { {16, 16, LLDB_INVALID_REGNUM, 16, 16}, nullptr, nullptr, - nullptr, - 0}, + }, {"r17", "", 4, @@ -232,8 +215,7 @@ static const RegisterInfo g_register_infos[] = { {17, 17, LLDB_INVALID_REGNUM, 17, 17}, nullptr, nullptr, - nullptr, - 0}, + }, {"r18", "", 4, @@ -243,8 +225,7 @@ static const RegisterInfo g_register_infos[] = { {18, 18, LLDB_INVALID_REGNUM, 18, 18}, nullptr, nullptr, - nullptr, - 0}, + }, {"r19", "", 4, @@ -254,8 +235,7 @@ static const RegisterInfo g_register_infos[] = { {19, 19, LLDB_INVALID_REGNUM, 19, 19}, nullptr, nullptr, - nullptr, - 0}, + }, {"r20", "", 4, @@ -265,8 +245,7 @@ static const RegisterInfo g_register_infos[] = { {20, 20, LLDB_INVALID_REGNUM, 20, 20}, nullptr, nullptr, - nullptr, - 0}, + }, {"r21", "", 4, @@ -276,8 +255,7 @@ static const RegisterInfo g_register_infos[] = { {21, 21, LLDB_INVALID_REGNUM, 21, 21}, nullptr, nullptr, - nullptr, - 0}, + }, {"r22", "", 4, @@ -287,8 +265,7 @@ static const RegisterInfo g_register_infos[] = { {22, 22, LLDB_INVALID_REGNUM, 22, 22}, nullptr, nullptr, - nullptr, - 0}, + }, {"r23", "", 4, @@ -298,8 +275,7 @@ static const RegisterInfo g_register_infos[] = { {23, 23, LLDB_INVALID_REGNUM, 23, 23}, nullptr, nullptr, - nullptr, - 0}, + }, {"r24", "", 4, @@ -309,8 +285,7 @@ static const RegisterInfo g_register_infos[] = { {24, 24, LLDB_INVALID_REGNUM, 24, 24}, nullptr, nullptr, - nullptr, - 0}, + }, {"r25", "", 4, @@ -320,8 +295,7 @@ static const RegisterInfo g_register_infos[] = { {25, 25, LLDB_INVALID_REGNUM, 25, 25}, nullptr, nullptr, - nullptr, - 0}, + }, {"r26", "", 4, @@ -331,8 +305,7 @@ static const RegisterInfo g_register_infos[] = { {26, 26, LLDB_INVALID_REGNUM, 26, 26}, nullptr, nullptr, - nullptr, - 0}, + }, {"r27", "", 4, @@ -342,8 +315,7 @@ static const RegisterInfo g_register_infos[] = { {27, 27, LLDB_INVALID_REGNUM, 27, 27}, nullptr, nullptr, - nullptr, - 0}, + }, {"r28", "", 4, @@ -353,8 +325,7 @@ static const RegisterInfo g_register_infos[] = { {28, 28, LLDB_INVALID_REGNUM, 28, 28}, nullptr, nullptr, - nullptr, - 0}, + }, {"sp", "r29", 4, @@ -364,8 +335,7 @@ static const RegisterInfo g_register_infos[] = { {29, 29, LLDB_REGNUM_GENERIC_SP, 29, 29}, nullptr, nullptr, - nullptr, - 0}, + }, {"fp", "r30", 4, @@ -375,8 +345,7 @@ static const RegisterInfo g_register_infos[] = { {30, 30, LLDB_REGNUM_GENERIC_FP, 30, 30}, nullptr, nullptr, - nullptr, - 0}, + }, {"lr", "r31", 4, @@ -386,8 +355,7 @@ static const RegisterInfo g_register_infos[] = { {31, 31, LLDB_REGNUM_GENERIC_RA, 31, 31}, nullptr, nullptr, - nullptr, - 0}, + }, {"sa0", "", 4, @@ -397,8 +365,7 @@ static const RegisterInfo g_register_infos[] = { {32, 32, LLDB_INVALID_REGNUM, 32, 32}, nullptr, nullptr, - nullptr, - 0}, + }, {"lc0", "", 4, @@ -408,8 +375,7 @@ static const RegisterInfo g_register_infos[] = { {33, 33, LLDB_INVALID_REGNUM, 33, 33}, nullptr, nullptr, - nullptr, - 0}, + }, {"sa1", "", 4, @@ -419,8 +385,7 @@ static const RegisterInfo g_register_infos[] = { {34, 34, LLDB_INVALID_REGNUM, 34, 34}, nullptr, nullptr, - nullptr, - 0}, + }, {"lc1", "", 4, @@ -430,8 +395,7 @@ static const RegisterInfo g_register_infos[] = { {35, 35, LLDB_INVALID_REGNUM, 35, 35}, nullptr, nullptr, - nullptr, - 0}, + }, // --> hexagon-v4/5/55/56-sim.xml {"p3_0", "", @@ -442,8 +406,7 @@ static const RegisterInfo g_register_infos[] = { {36, 36, LLDB_INVALID_REGNUM, 36, 36}, nullptr, nullptr, - nullptr, - 0}, + }, // PADDING { {"p00", "", @@ -454,8 +417,7 @@ static const RegisterInfo g_register_infos[] = { {37, 37, LLDB_INVALID_REGNUM, 37, 37}, nullptr, nullptr, - nullptr, - 0}, + }, // } {"m0", "", @@ -466,8 +428,7 @@ static const RegisterInfo g_register_infos[] = { {38, 38, LLDB_INVALID_REGNUM, 38, 38}, nullptr, nullptr, - nullptr, - 0}, + }, {"m1", "", 4, @@ -477,8 +438,7 @@ static const RegisterInfo g_register_infos[] = { {39, 39, LLDB_INVALID_REGNUM, 39, 39}, nullptr, nullptr, - nullptr, - 0}, + }, {"usr", "", 4, @@ -488,8 +448,7 @@ static const RegisterInfo g_register_infos[] = { {40, 40, LLDB_INVALID_REGNUM, 40, 40}, nullptr, nullptr, - nullptr, - 0}, + }, {"pc", "", 4, @@ -499,8 +458,7 @@ static const RegisterInfo g_register_infos[] = { {41, 41, LLDB_REGNUM_GENERIC_PC, 41, 41}, nullptr, nullptr, - nullptr, - 0}, + }, {"ugp", "", 4, @@ -510,8 +468,7 @@ static const RegisterInfo g_register_infos[] = { {42, 42, LLDB_INVALID_REGNUM, 42, 42}, nullptr, nullptr, - nullptr, - 0}, + }, {"gp", "", 4, @@ -521,8 +478,7 @@ static const RegisterInfo g_register_infos[] = { {43, 43, LLDB_INVALID_REGNUM, 43, 43}, nullptr, nullptr, - nullptr, - 0}, + }, {"cs0", "", 4, @@ -532,8 +488,7 @@ static const RegisterInfo g_register_infos[] = { {44, 44, LLDB_INVALID_REGNUM, 44, 44}, nullptr, nullptr, - nullptr, - 0}, + }, {"cs1", "", 4, @@ -543,8 +498,7 @@ static const RegisterInfo g_register_infos[] = { {45, 45, LLDB_INVALID_REGNUM, 45, 45}, nullptr, nullptr, - nullptr, - 0}, + }, // PADDING { {"p01", "", @@ -555,8 +509,7 @@ static const RegisterInfo g_register_infos[] = { {46, 46, LLDB_INVALID_REGNUM, 46, 46}, nullptr, nullptr, - nullptr, - 0}, + }, {"p02", "", 4, @@ -566,8 +519,7 @@ static const RegisterInfo g_register_infos[] = { {47, 47, LLDB_INVALID_REGNUM, 47, 47}, nullptr, nullptr, - nullptr, - 0}, + }, {"p03", "", 4, @@ -577,8 +529,7 @@ static const RegisterInfo g_register_infos[] = { {48, 48, LLDB_INVALID_REGNUM, 48, 48}, nullptr, nullptr, - nullptr, - 0}, + }, {"p04", "", 4, @@ -588,8 +539,7 @@ static const RegisterInfo g_register_infos[] = { {49, 49, LLDB_INVALID_REGNUM, 49, 49}, nullptr, nullptr, - nullptr, - 0}, + }, {"p05", "", 4, @@ -599,8 +549,7 @@ static const RegisterInfo g_register_infos[] = { {50, 50, LLDB_INVALID_REGNUM, 50, 50}, nullptr, nullptr, - nullptr, - 0}, + }, {"p06", "", 4, @@ -610,8 +559,7 @@ static const RegisterInfo g_register_infos[] = { {51, 51, LLDB_INVALID_REGNUM, 51, 51}, nullptr, nullptr, - nullptr, - 0}, + }, {"p07", "", 4, @@ -621,8 +569,7 @@ static const RegisterInfo g_register_infos[] = { {52, 52, LLDB_INVALID_REGNUM, 52, 52}, nullptr, nullptr, - nullptr, - 0}, + }, {"p08", "", 4, @@ -632,8 +579,7 @@ static const RegisterInfo g_register_infos[] = { {53, 53, LLDB_INVALID_REGNUM, 53, 53}, nullptr, nullptr, - nullptr, - 0}, + }, {"p09", "", 4, @@ -643,8 +589,7 @@ static const RegisterInfo g_register_infos[] = { {54, 54, LLDB_INVALID_REGNUM, 54, 54}, nullptr, nullptr, - nullptr, - 0}, + }, {"p10", "", 4, @@ -654,8 +599,7 @@ static const RegisterInfo g_register_infos[] = { {55, 55, LLDB_INVALID_REGNUM, 55, 55}, nullptr, nullptr, - nullptr, - 0}, + }, {"p11", "", 4, @@ -665,8 +609,7 @@ static const RegisterInfo g_register_infos[] = { {56, 56, LLDB_INVALID_REGNUM, 56, 56}, nullptr, nullptr, - nullptr, - 0}, + }, {"p12", "", 4, @@ -676,8 +619,7 @@ static const RegisterInfo g_register_infos[] = { {57, 57, LLDB_INVALID_REGNUM, 57, 57}, nullptr, nullptr, - nullptr, - 0}, + }, {"p13", "", 4, @@ -687,8 +629,7 @@ static const RegisterInfo g_register_infos[] = { {58, 58, LLDB_INVALID_REGNUM, 58, 58}, nullptr, nullptr, - nullptr, - 0}, + }, {"p14", "", 4, @@ -698,8 +639,7 @@ static const RegisterInfo g_register_infos[] = { {59, 59, LLDB_INVALID_REGNUM, 59, 59}, nullptr, nullptr, - nullptr, - 0}, + }, {"p15", "", 4, @@ -709,8 +649,7 @@ static const RegisterInfo g_register_infos[] = { {60, 60, LLDB_INVALID_REGNUM, 60, 60}, nullptr, nullptr, - nullptr, - 0}, + }, {"p16", "", 4, @@ -720,8 +659,7 @@ static const RegisterInfo g_register_infos[] = { {61, 61, LLDB_INVALID_REGNUM, 61, 61}, nullptr, nullptr, - nullptr, - 0}, + }, {"p17", "", 4, @@ -731,8 +669,7 @@ static const RegisterInfo g_register_infos[] = { {62, 62, LLDB_INVALID_REGNUM, 62, 62}, nullptr, nullptr, - nullptr, - 0}, + }, {"p18", "", 4, @@ -742,8 +679,7 @@ static const RegisterInfo g_register_infos[] = { {63, 63, LLDB_INVALID_REGNUM, 63, 63}, nullptr, nullptr, - nullptr, - 0}, + }, // } {"sgp0", "", @@ -754,8 +690,7 @@ static const RegisterInfo g_register_infos[] = { {64, 64, LLDB_INVALID_REGNUM, 64, 64}, nullptr, nullptr, - nullptr, - 0}, + }, // PADDING { {"p19", "", @@ -766,8 +701,7 @@ static const RegisterInfo g_register_infos[] = { {65, 65, LLDB_INVALID_REGNUM, 65, 65}, nullptr, nullptr, - nullptr, - 0}, + }, // } {"stid", "", @@ -778,8 +712,7 @@ static const RegisterInfo g_register_infos[] = { {66, 66, LLDB_INVALID_REGNUM, 66, 66}, nullptr, nullptr, - nullptr, - 0}, + }, {"elr", "", 4, @@ -789,8 +722,7 @@ static const RegisterInfo g_register_infos[] = { {67, 67, LLDB_INVALID_REGNUM, 67, 67}, nullptr, nullptr, - nullptr, - 0}, + }, {"badva0", "", 4, @@ -800,8 +732,7 @@ static const RegisterInfo g_register_infos[] = { {68, 68, LLDB_INVALID_REGNUM, 68, 68}, nullptr, nullptr, - nullptr, - 0}, + }, {"badva1", "", 4, @@ -811,8 +742,7 @@ static const RegisterInfo g_register_infos[] = { {69, 69, LLDB_INVALID_REGNUM, 69, 69}, nullptr, nullptr, - nullptr, - 0}, + }, {"ssr", "", 4, @@ -822,8 +752,7 @@ static const RegisterInfo g_register_infos[] = { {70, 70, LLDB_INVALID_REGNUM, 70, 70}, nullptr, nullptr, - nullptr, - 0}, + }, {"ccr", "", 4, @@ -833,8 +762,7 @@ static const RegisterInfo g_register_infos[] = { {71, 71, LLDB_INVALID_REGNUM, 71, 71}, nullptr, nullptr, - nullptr, - 0}, + }, {"htid", "", 4, @@ -844,8 +772,7 @@ static const RegisterInfo g_register_infos[] = { {72, 72, LLDB_INVALID_REGNUM, 72, 72}, nullptr, nullptr, - nullptr, - 0}, + }, // PADDING { {"p20", "", @@ -856,8 +783,7 @@ static const RegisterInfo g_register_infos[] = { {73, 73, LLDB_INVALID_REGNUM, 73, 73}, nullptr, nullptr, - nullptr, - 0}, + }, // } {"imask", "", @@ -868,8 +794,7 @@ static const RegisterInfo g_register_infos[] = { {74, 74, LLDB_INVALID_REGNUM, 74, 74}, nullptr, nullptr, - nullptr, - 0}, + }, // PADDING { {"p21", "", @@ -880,8 +805,7 @@ static const RegisterInfo g_register_infos[] = { {75, 75, LLDB_INVALID_REGNUM, 75, 75}, nullptr, nullptr, - nullptr, - 0}, + }, {"p22", "", 4, @@ -891,8 +815,7 @@ static const RegisterInfo g_register_infos[] = { {76, 76, LLDB_INVALID_REGNUM, 76, 76}, nullptr, nullptr, - nullptr, - 0}, + }, {"p23", "", 4, @@ -902,8 +825,7 @@ static const RegisterInfo g_register_infos[] = { {77, 77, LLDB_INVALID_REGNUM, 77, 77}, nullptr, nullptr, - nullptr, - 0}, + }, {"p24", "", 4, @@ -913,8 +835,7 @@ static const RegisterInfo g_register_infos[] = { {78, 78, LLDB_INVALID_REGNUM, 78, 78}, nullptr, nullptr, - nullptr, - 0}, + }, {"p25", "", 4, @@ -924,8 +845,7 @@ static const RegisterInfo g_register_infos[] = { {79, 79, LLDB_INVALID_REGNUM, 79, 79}, nullptr, nullptr, - nullptr, - 0}, + }, // } {"g0", "", @@ -936,8 +856,7 @@ static const RegisterInfo g_register_infos[] = { {80, 80, LLDB_INVALID_REGNUM, 80, 80}, nullptr, nullptr, - nullptr, - 0}, + }, {"g1", "", 4, @@ -947,8 +866,7 @@ static const RegisterInfo g_register_infos[] = { {81, 81, LLDB_INVALID_REGNUM, 81, 81}, nullptr, nullptr, - nullptr, - 0}, + }, {"g2", "", 4, @@ -958,8 +876,7 @@ static const RegisterInfo g_register_infos[] = { {82, 82, LLDB_INVALID_REGNUM, 82, 82}, nullptr, nullptr, - nullptr, - 0}, + }, {"g3", "", 4, @@ -969,8 +886,7 @@ static const RegisterInfo g_register_infos[] = { {83, 83, LLDB_INVALID_REGNUM, 83, 83}, nullptr, nullptr, - nullptr, - 0}}; + }}; static const uint32_t k_num_register_infos = sizeof(g_register_infos) / sizeof(RegisterInfo); @@ -1277,19 +1193,6 @@ void ABISysV_hexagon::Terminate() { PluginManager::UnregisterPlugin(CreateInstance); } -lldb_private::ConstString ABISysV_hexagon::GetPluginNameStatic() { - static ConstString g_name("sysv-hexagon"); - return g_name; -} - -// PluginInterface protocol - -lldb_private::ConstString ABISysV_hexagon::GetPluginName() { - return GetPluginNameStatic(); -} - -uint32_t ABISysV_hexagon::GetPluginVersion() { return 1; } - // get value object specialized to work with llvm IR types lldb::ValueObjectSP ABISysV_hexagon::GetReturnValueObjectImpl(lldb_private::Thread &thread, diff --git a/contrib/llvm-project/lldb/source/Plugins/ABI/Hexagon/ABISysV_hexagon.h b/contrib/llvm-project/lldb/source/Plugins/ABI/Hexagon/ABISysV_hexagon.h index d6dab0c2e378..df7016926d79 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ABI/Hexagon/ABISysV_hexagon.h +++ b/contrib/llvm-project/lldb/source/Plugins/ABI/Hexagon/ABISysV_hexagon.h @@ -79,13 +79,11 @@ public: static lldb::ABISP CreateInstance(lldb::ProcessSP process_sp, const lldb_private::ArchSpec &arch); - static lldb_private::ConstString GetPluginNameStatic(); + static llvm::StringRef GetPluginNameStatic() { return "sysv-hexagon"; } // PluginInterface protocol - lldb_private::ConstString GetPluginName() override; - - uint32_t GetPluginVersion() override; + llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); } protected: void CreateRegisterMapIfNeeded(); diff --git a/contrib/llvm-project/lldb/source/Plugins/ABI/Mips/ABISysV_mips.cpp b/contrib/llvm-project/lldb/source/Plugins/ABI/Mips/ABISysV_mips.cpp index 538ec06c3b0d..662689ca0615 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ABI/Mips/ABISysV_mips.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/ABI/Mips/ABISysV_mips.cpp @@ -92,8 +92,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"r1", "AT", 4, @@ -104,8 +103,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"r2", "v0", 4, @@ -116,8 +114,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"r3", "v1", 4, @@ -128,10 +125,9 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"r4", - "arg1", + nullptr, 4, 0, eEncodingUint, @@ -140,10 +136,9 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"r5", - "arg2", + nullptr, 4, 0, eEncodingUint, @@ -152,10 +147,9 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"r6", - "arg3", + nullptr, 4, 0, eEncodingUint, @@ -164,10 +158,9 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"r7", - "arg4", + nullptr, 4, 0, eEncodingUint, @@ -176,8 +169,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"r8", "arg5", 4, @@ -188,8 +180,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"r9", "arg6", 4, @@ -200,8 +191,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"r10", "arg7", 4, @@ -212,8 +202,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"r11", "arg8", 4, @@ -224,8 +213,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"r12", nullptr, 4, @@ -236,8 +224,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"r13", nullptr, 4, @@ -248,8 +235,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"r14", nullptr, 4, @@ -260,8 +246,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"r15", nullptr, 4, @@ -272,8 +257,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"r16", nullptr, 4, @@ -284,8 +268,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"r17", nullptr, 4, @@ -296,8 +279,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"r18", nullptr, 4, @@ -308,8 +290,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"r19", nullptr, 4, @@ -320,8 +301,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"r20", nullptr, 4, @@ -332,8 +312,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"r21", nullptr, 4, @@ -344,8 +323,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"r22", nullptr, 4, @@ -356,8 +334,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"r23", nullptr, 4, @@ -368,8 +345,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"r24", nullptr, 4, @@ -380,8 +356,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"r25", nullptr, 4, @@ -392,8 +367,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"r26", nullptr, 4, @@ -404,8 +378,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"r27", nullptr, 4, @@ -416,8 +389,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"r28", "gp", 4, @@ -428,10 +400,9 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"r29", - "sp", + nullptr, 4, 0, eEncodingUint, @@ -440,10 +411,9 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"r30", - "fp", + nullptr, 4, 0, eEncodingUint, @@ -452,10 +422,9 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"r31", - "ra", + nullptr, 4, 0, eEncodingUint, @@ -464,8 +433,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"sr", nullptr, 4, @@ -476,8 +444,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"lo", nullptr, 4, @@ -488,8 +455,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"hi", nullptr, 4, @@ -500,8 +466,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"bad", nullptr, 4, @@ -512,8 +477,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"cause", nullptr, 4, @@ -524,8 +488,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"pc", nullptr, 4, @@ -536,8 +499,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, }; static const uint32_t k_num_register_infos = @@ -1052,16 +1014,3 @@ void ABISysV_mips::Initialize() { void ABISysV_mips::Terminate() { PluginManager::UnregisterPlugin(CreateInstance); } - -lldb_private::ConstString ABISysV_mips::GetPluginNameStatic() { - static ConstString g_name("sysv-mips"); - return g_name; -} - -// PluginInterface protocol - -lldb_private::ConstString ABISysV_mips::GetPluginName() { - return GetPluginNameStatic(); -} - -uint32_t ABISysV_mips::GetPluginVersion() { return 1; } diff --git a/contrib/llvm-project/lldb/source/Plugins/ABI/Mips/ABISysV_mips.h b/contrib/llvm-project/lldb/source/Plugins/ABI/Mips/ABISysV_mips.h index 715405e7ef97..e77a8bfc0ab6 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ABI/Mips/ABISysV_mips.h +++ b/contrib/llvm-project/lldb/source/Plugins/ABI/Mips/ABISysV_mips.h @@ -69,13 +69,11 @@ public: static lldb::ABISP CreateInstance(lldb::ProcessSP process_sp, const lldb_private::ArchSpec &arch); - static lldb_private::ConstString GetPluginNameStatic(); + static llvm::StringRef GetPluginNameStatic() { return "sysv-mips"; } // PluginInterface protocol - lldb_private::ConstString GetPluginName() override; - - uint32_t GetPluginVersion() override; + llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); } protected: void CreateRegisterMapIfNeeded(); diff --git a/contrib/llvm-project/lldb/source/Plugins/ABI/Mips/ABISysV_mips64.cpp b/contrib/llvm-project/lldb/source/Plugins/ABI/Mips/ABISysV_mips64.cpp index 7220508c75ff..7e272265e15d 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ABI/Mips/ABISysV_mips64.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/ABI/Mips/ABISysV_mips64.cpp @@ -92,8 +92,7 @@ static const RegisterInfo g_register_infos_mips64[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"r1", "AT", 8, @@ -104,8 +103,7 @@ static const RegisterInfo g_register_infos_mips64[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"r2", "v0", 8, @@ -116,8 +114,7 @@ static const RegisterInfo g_register_infos_mips64[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"r3", "v1", 8, @@ -128,10 +125,9 @@ static const RegisterInfo g_register_infos_mips64[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"r4", - "arg1", + nullptr, 8, 0, eEncodingUint, @@ -140,10 +136,9 @@ static const RegisterInfo g_register_infos_mips64[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"r5", - "arg2", + nullptr, 8, 0, eEncodingUint, @@ -152,10 +147,9 @@ static const RegisterInfo g_register_infos_mips64[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"r6", - "arg3", + nullptr, 8, 0, eEncodingUint, @@ -164,10 +158,9 @@ static const RegisterInfo g_register_infos_mips64[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"r7", - "arg4", + nullptr, 8, 0, eEncodingUint, @@ -176,10 +169,9 @@ static const RegisterInfo g_register_infos_mips64[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"r8", - "arg5", + nullptr, 8, 0, eEncodingUint, @@ -188,10 +180,9 @@ static const RegisterInfo g_register_infos_mips64[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"r9", - "arg6", + nullptr, 8, 0, eEncodingUint, @@ -200,10 +191,9 @@ static const RegisterInfo g_register_infos_mips64[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"r10", - "arg7", + nullptr, 8, 0, eEncodingUint, @@ -212,10 +202,9 @@ static const RegisterInfo g_register_infos_mips64[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"r11", - "arg8", + nullptr, 8, 0, eEncodingUint, @@ -224,8 +213,7 @@ static const RegisterInfo g_register_infos_mips64[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"r12", nullptr, 8, @@ -236,8 +224,7 @@ static const RegisterInfo g_register_infos_mips64[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"r13", nullptr, 8, @@ -248,8 +235,7 @@ static const RegisterInfo g_register_infos_mips64[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"r14", nullptr, 8, @@ -260,8 +246,7 @@ static const RegisterInfo g_register_infos_mips64[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"r15", nullptr, 8, @@ -272,8 +257,7 @@ static const RegisterInfo g_register_infos_mips64[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"r16", nullptr, 8, @@ -284,8 +268,7 @@ static const RegisterInfo g_register_infos_mips64[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"r17", nullptr, 8, @@ -296,8 +279,7 @@ static const RegisterInfo g_register_infos_mips64[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"r18", nullptr, 8, @@ -308,8 +290,7 @@ static const RegisterInfo g_register_infos_mips64[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"r19", nullptr, 8, @@ -320,8 +301,7 @@ static const RegisterInfo g_register_infos_mips64[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"r20", nullptr, 8, @@ -332,8 +312,7 @@ static const RegisterInfo g_register_infos_mips64[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"r21", nullptr, 8, @@ -344,8 +323,7 @@ static const RegisterInfo g_register_infos_mips64[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"r22", nullptr, 8, @@ -356,8 +334,7 @@ static const RegisterInfo g_register_infos_mips64[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"r23", nullptr, 8, @@ -368,8 +345,7 @@ static const RegisterInfo g_register_infos_mips64[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"r24", nullptr, 8, @@ -380,8 +356,7 @@ static const RegisterInfo g_register_infos_mips64[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"r25", nullptr, 8, @@ -392,8 +367,7 @@ static const RegisterInfo g_register_infos_mips64[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"r26", nullptr, 8, @@ -404,8 +378,7 @@ static const RegisterInfo g_register_infos_mips64[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"r27", nullptr, 8, @@ -416,8 +389,7 @@ static const RegisterInfo g_register_infos_mips64[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"r28", "gp", 8, @@ -428,10 +400,9 @@ static const RegisterInfo g_register_infos_mips64[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"r29", - "sp", + nullptr, 8, 0, eEncodingUint, @@ -440,10 +411,9 @@ static const RegisterInfo g_register_infos_mips64[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"r30", - "fp", + nullptr, 8, 0, eEncodingUint, @@ -452,10 +422,9 @@ static const RegisterInfo g_register_infos_mips64[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"r31", - "ra", + nullptr, 8, 0, eEncodingUint, @@ -464,8 +433,7 @@ static const RegisterInfo g_register_infos_mips64[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"sr", nullptr, 4, @@ -476,8 +444,7 @@ static const RegisterInfo g_register_infos_mips64[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"lo", nullptr, 8, @@ -488,8 +455,7 @@ static const RegisterInfo g_register_infos_mips64[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"hi", nullptr, 8, @@ -500,8 +466,7 @@ static const RegisterInfo g_register_infos_mips64[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"bad", nullptr, 8, @@ -512,8 +477,7 @@ static const RegisterInfo g_register_infos_mips64[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"cause", nullptr, 8, @@ -524,8 +488,7 @@ static const RegisterInfo g_register_infos_mips64[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, {"pc", nullptr, 8, @@ -536,8 +499,7 @@ static const RegisterInfo g_register_infos_mips64[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}, + }, }; static const uint32_t k_num_register_infos = @@ -1200,16 +1162,3 @@ void ABISysV_mips64::Initialize() { void ABISysV_mips64::Terminate() { PluginManager::UnregisterPlugin(CreateInstance); } - -lldb_private::ConstString ABISysV_mips64::GetPluginNameStatic() { - static ConstString g_name("sysv-mips64"); - return g_name; -} - -// PluginInterface protocol - -lldb_private::ConstString ABISysV_mips64::GetPluginName() { - return GetPluginNameStatic(); -} - -uint32_t ABISysV_mips64::GetPluginVersion() { return 1; } diff --git a/contrib/llvm-project/lldb/source/Plugins/ABI/Mips/ABISysV_mips64.h b/contrib/llvm-project/lldb/source/Plugins/ABI/Mips/ABISysV_mips64.h index 91428216a73a..3eda3992e65e 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ABI/Mips/ABISysV_mips64.h +++ b/contrib/llvm-project/lldb/source/Plugins/ABI/Mips/ABISysV_mips64.h @@ -82,13 +82,11 @@ public: static lldb::ABISP CreateInstance(lldb::ProcessSP process_sp, const lldb_private::ArchSpec &arch); - static lldb_private::ConstString GetPluginNameStatic(); + static llvm::StringRef GetPluginNameStatic() { return "sysv-mips64"; } // PluginInterface protocol - lldb_private::ConstString GetPluginName() override; - - uint32_t GetPluginVersion() override; + llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); } protected: void CreateRegisterMapIfNeeded(); diff --git a/contrib/llvm-project/lldb/source/Plugins/ABI/PowerPC/ABISysV_ppc.cpp b/contrib/llvm-project/lldb/source/Plugins/ABI/PowerPC/ABISysV_ppc.cpp index 98a14b50cbf3..70b9c46d353f 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ABI/PowerPC/ABISysV_ppc.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/ABI/PowerPC/ABISysV_ppc.cpp @@ -112,7 +112,7 @@ enum dwarf_regnums { #define DEFINE_GPR(reg, alt, kind1, kind2, kind3, kind4) \ { \ #reg, alt, 8, 0, eEncodingUint, eFormatHex, {kind1, kind2, kind3, kind4 }, \ - nullptr, nullptr, nullptr, 0 \ + nullptr, nullptr, \ } static const RegisterInfo g_register_infos[] = { @@ -120,25 +120,25 @@ static const RegisterInfo g_register_infos[] = { // Generic, Process Plugin DEFINE_GPR(r0, nullptr, dwarf_r0, dwarf_r0, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), - DEFINE_GPR(r1, "sp", dwarf_r1, dwarf_r1, LLDB_REGNUM_GENERIC_SP, + DEFINE_GPR(r1, nullptr, dwarf_r1, dwarf_r1, LLDB_REGNUM_GENERIC_SP, LLDB_INVALID_REGNUM), DEFINE_GPR(r2, nullptr, dwarf_r2, dwarf_r2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), - DEFINE_GPR(r3, "arg1", dwarf_r3, dwarf_r3, LLDB_REGNUM_GENERIC_ARG1, + DEFINE_GPR(r3, nullptr, dwarf_r3, dwarf_r3, LLDB_REGNUM_GENERIC_ARG1, LLDB_INVALID_REGNUM), - DEFINE_GPR(r4, "arg2", dwarf_r4, dwarf_r4, LLDB_REGNUM_GENERIC_ARG2, + DEFINE_GPR(r4, nullptr, dwarf_r4, dwarf_r4, LLDB_REGNUM_GENERIC_ARG2, LLDB_INVALID_REGNUM), - DEFINE_GPR(r5, "arg3", dwarf_r5, dwarf_r5, LLDB_REGNUM_GENERIC_ARG3, + DEFINE_GPR(r5, nullptr, dwarf_r5, dwarf_r5, LLDB_REGNUM_GENERIC_ARG3, LLDB_INVALID_REGNUM), - DEFINE_GPR(r6, "arg4", dwarf_r6, dwarf_r6, LLDB_REGNUM_GENERIC_ARG4, + DEFINE_GPR(r6, nullptr, dwarf_r6, dwarf_r6, LLDB_REGNUM_GENERIC_ARG4, LLDB_INVALID_REGNUM), - DEFINE_GPR(r7, "arg5", dwarf_r7, dwarf_r7, LLDB_REGNUM_GENERIC_ARG5, + DEFINE_GPR(r7, nullptr, dwarf_r7, dwarf_r7, LLDB_REGNUM_GENERIC_ARG5, LLDB_INVALID_REGNUM), - DEFINE_GPR(r8, "arg6", dwarf_r8, dwarf_r8, LLDB_REGNUM_GENERIC_ARG6, + DEFINE_GPR(r8, nullptr, dwarf_r8, dwarf_r8, LLDB_REGNUM_GENERIC_ARG6, LLDB_INVALID_REGNUM), - DEFINE_GPR(r9, "arg7", dwarf_r9, dwarf_r9, LLDB_REGNUM_GENERIC_ARG7, + DEFINE_GPR(r9, nullptr, dwarf_r9, dwarf_r9, LLDB_REGNUM_GENERIC_ARG7, LLDB_INVALID_REGNUM), - DEFINE_GPR(r10, "arg8", dwarf_r10, dwarf_r10, LLDB_REGNUM_GENERIC_ARG8, + DEFINE_GPR(r10, nullptr, dwarf_r10, dwarf_r10, LLDB_REGNUM_GENERIC_ARG8, LLDB_INVALID_REGNUM), DEFINE_GPR(r11, nullptr, dwarf_r11, dwarf_r11, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), @@ -182,15 +182,15 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM), DEFINE_GPR(r31, nullptr, dwarf_r31, dwarf_r31, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), - DEFINE_GPR(lr, "lr", dwarf_lr, dwarf_lr, LLDB_REGNUM_GENERIC_RA, + DEFINE_GPR(lr, nullptr, dwarf_lr, dwarf_lr, LLDB_REGNUM_GENERIC_RA, LLDB_INVALID_REGNUM), - DEFINE_GPR(cr, "cr", dwarf_cr, dwarf_cr, LLDB_REGNUM_GENERIC_FLAGS, + DEFINE_GPR(cr, nullptr, dwarf_cr, dwarf_cr, LLDB_REGNUM_GENERIC_FLAGS, LLDB_INVALID_REGNUM), - DEFINE_GPR(xer, "xer", dwarf_xer, dwarf_xer, LLDB_INVALID_REGNUM, + DEFINE_GPR(xer, nullptr, dwarf_xer, dwarf_xer, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), - DEFINE_GPR(ctr, "ctr", dwarf_ctr, dwarf_ctr, LLDB_INVALID_REGNUM, + DEFINE_GPR(ctr, nullptr, dwarf_ctr, dwarf_ctr, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), - DEFINE_GPR(pc, "pc", dwarf_pc, dwarf_pc, LLDB_REGNUM_GENERIC_PC, + DEFINE_GPR(pc, nullptr, dwarf_pc, dwarf_pc, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_REGNUM), {nullptr, nullptr, @@ -201,8 +201,7 @@ static const RegisterInfo g_register_infos[] = { {dwarf_cfa, dwarf_cfa, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, - nullptr, - 0}}; + }}; static const uint32_t k_num_register_infos = llvm::array_lengthof(g_register_infos); @@ -963,16 +962,3 @@ void ABISysV_ppc::Initialize() { void ABISysV_ppc::Terminate() { PluginManager::UnregisterPlugin(CreateInstance); } - -lldb_private::ConstString ABISysV_ppc::GetPluginNameStatic() { - static ConstString g_name("sysv-ppc"); - return g_name; -} - -// PluginInterface protocol - -lldb_private::ConstString ABISysV_ppc::GetPluginName() { - return GetPluginNameStatic(); -} - -uint32_t ABISysV_ppc::GetPluginVersion() { return 1; } diff --git a/contrib/llvm-project/lldb/source/Plugins/ABI/PowerPC/ABISysV_ppc.h b/contrib/llvm-project/lldb/source/Plugins/ABI/PowerPC/ABISysV_ppc.h index 4a586849e585..21b970f87934 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ABI/PowerPC/ABISysV_ppc.h +++ b/contrib/llvm-project/lldb/source/Plugins/ABI/PowerPC/ABISysV_ppc.h @@ -78,13 +78,11 @@ public: static lldb::ABISP CreateInstance(lldb::ProcessSP process_sp, const lldb_private::ArchSpec &arch); - static lldb_private::ConstString GetPluginNameStatic(); + static llvm::StringRef GetPluginNameStatic() { return "sysv-ppc"; } // PluginInterface protocol - lldb_private::ConstString GetPluginName() override; - - uint32_t GetPluginVersion() override; + llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); } protected: void CreateRegisterMapIfNeeded(); diff --git a/contrib/llvm-project/lldb/source/Plugins/ABI/PowerPC/ABISysV_ppc64.cpp b/contrib/llvm-project/lldb/source/Plugins/ABI/PowerPC/ABISysV_ppc64.cpp index 7cc9482e7c5d..f9a2851d3949 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ABI/PowerPC/ABISysV_ppc64.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/ABI/PowerPC/ABISysV_ppc64.cpp @@ -1074,16 +1074,3 @@ void ABISysV_ppc64::Initialize() { void ABISysV_ppc64::Terminate() { PluginManager::UnregisterPlugin(CreateInstance); } - -lldb_private::ConstString ABISysV_ppc64::GetPluginNameStatic() { - static ConstString g_name("sysv-ppc64"); - return g_name; -} - -// PluginInterface protocol - -lldb_private::ConstString ABISysV_ppc64::GetPluginName() { - return GetPluginNameStatic(); -} - -uint32_t ABISysV_ppc64::GetPluginVersion() { return 1; } diff --git a/contrib/llvm-project/lldb/source/Plugins/ABI/PowerPC/ABISysV_ppc64.h b/contrib/llvm-project/lldb/source/Plugins/ABI/PowerPC/ABISysV_ppc64.h index 8dcf3ca48b56..bfa96cc0df70 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ABI/PowerPC/ABISysV_ppc64.h +++ b/contrib/llvm-project/lldb/source/Plugins/ABI/PowerPC/ABISysV_ppc64.h @@ -78,13 +78,11 @@ public: static lldb::ABISP CreateInstance(lldb::ProcessSP process_sp, const lldb_private::ArchSpec &arch); - static lldb_private::ConstString GetPluginNameStatic(); + static llvm::StringRef GetPluginNameStatic() { return "sysv-ppc64"; } // PluginInterface protocol - lldb_private::ConstString GetPluginName() override; - - uint32_t GetPluginVersion() override; + llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); } protected: void CreateRegisterMapIfNeeded(); diff --git a/contrib/llvm-project/lldb/source/Plugins/ABI/SystemZ/ABISysV_s390x.cpp b/contrib/llvm-project/lldb/source/Plugins/ABI/SystemZ/ABISysV_s390x.cpp index 88e85111d871..f8156deb7e30 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ABI/SystemZ/ABISysV_s390x.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/ABI/SystemZ/ABISysV_s390x.cpp @@ -115,22 +115,22 @@ enum dwarf_regnums { #name, alt, size, 0, eEncodingUint, eFormatHex, \ {dwarf_##name##_s390x, dwarf_##name##_s390x, generic, \ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, \ - nullptr, nullptr, nullptr, 0 \ + nullptr, nullptr, \ } static const RegisterInfo g_register_infos[] = { DEFINE_REG(r0, 8, nullptr, LLDB_INVALID_REGNUM), DEFINE_REG(r1, 8, nullptr, LLDB_INVALID_REGNUM), - DEFINE_REG(r2, 8, "arg1", LLDB_REGNUM_GENERIC_ARG1), - DEFINE_REG(r3, 8, "arg2", LLDB_REGNUM_GENERIC_ARG2), - DEFINE_REG(r4, 8, "arg3", LLDB_REGNUM_GENERIC_ARG3), - DEFINE_REG(r5, 8, "arg4", LLDB_REGNUM_GENERIC_ARG4), - DEFINE_REG(r6, 8, "arg5", LLDB_REGNUM_GENERIC_ARG5), + DEFINE_REG(r2, 8, nullptr, LLDB_REGNUM_GENERIC_ARG1), + DEFINE_REG(r3, 8, nullptr, LLDB_REGNUM_GENERIC_ARG2), + DEFINE_REG(r4, 8, nullptr, LLDB_REGNUM_GENERIC_ARG3), + DEFINE_REG(r5, 8, nullptr, LLDB_REGNUM_GENERIC_ARG4), + DEFINE_REG(r6, 8, nullptr, LLDB_REGNUM_GENERIC_ARG5), DEFINE_REG(r7, 8, nullptr, LLDB_INVALID_REGNUM), DEFINE_REG(r8, 8, nullptr, LLDB_INVALID_REGNUM), DEFINE_REG(r9, 8, nullptr, LLDB_INVALID_REGNUM), DEFINE_REG(r10, 8, nullptr, LLDB_INVALID_REGNUM), - DEFINE_REG(r11, 8, "fp", LLDB_REGNUM_GENERIC_FP), + DEFINE_REG(r11, 8, nullptr, LLDB_REGNUM_GENERIC_FP), DEFINE_REG(r12, 8, nullptr, LLDB_INVALID_REGNUM), DEFINE_REG(r13, 8, nullptr, LLDB_INVALID_REGNUM), DEFINE_REG(r14, 8, nullptr, LLDB_INVALID_REGNUM), @@ -151,8 +151,8 @@ static const RegisterInfo g_register_infos[] = { DEFINE_REG(acr13, 4, nullptr, LLDB_INVALID_REGNUM), DEFINE_REG(acr14, 4, nullptr, LLDB_INVALID_REGNUM), DEFINE_REG(acr15, 4, nullptr, LLDB_INVALID_REGNUM), - DEFINE_REG(pswm, 8, "flags", LLDB_REGNUM_GENERIC_FLAGS), - DEFINE_REG(pswa, 8, "pc", LLDB_REGNUM_GENERIC_PC), + DEFINE_REG(pswm, 8, nullptr, LLDB_REGNUM_GENERIC_FLAGS), + DEFINE_REG(pswa, 8, nullptr, LLDB_REGNUM_GENERIC_PC), DEFINE_REG(f0, 8, nullptr, LLDB_INVALID_REGNUM), DEFINE_REG(f1, 8, nullptr, LLDB_INVALID_REGNUM), DEFINE_REG(f2, 8, nullptr, LLDB_INVALID_REGNUM), @@ -716,16 +716,3 @@ void ABISysV_s390x::Initialize() { void ABISysV_s390x::Terminate() { PluginManager::UnregisterPlugin(CreateInstance); } - -lldb_private::ConstString ABISysV_s390x::GetPluginNameStatic() { - static ConstString g_name("sysv-s390x"); - return g_name; -} - -// PluginInterface protocol - -lldb_private::ConstString ABISysV_s390x::GetPluginName() { - return GetPluginNameStatic(); -} - -uint32_t ABISysV_s390x::GetPluginVersion() { return 1; } diff --git a/contrib/llvm-project/lldb/source/Plugins/ABI/SystemZ/ABISysV_s390x.h b/contrib/llvm-project/lldb/source/Plugins/ABI/SystemZ/ABISysV_s390x.h index f8f412465658..f6c248dc59ba 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ABI/SystemZ/ABISysV_s390x.h +++ b/contrib/llvm-project/lldb/source/Plugins/ABI/SystemZ/ABISysV_s390x.h @@ -70,13 +70,11 @@ public: static lldb::ABISP CreateInstance(lldb::ProcessSP process_sp, const lldb_private::ArchSpec &arch); - static lldb_private::ConstString GetPluginNameStatic(); + static llvm::StringRef GetPluginNameStatic() { return "sysv-s390x"; } // PluginInterface protocol - lldb_private::ConstString GetPluginName() override; - - uint32_t GetPluginVersion() override; + llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); } protected: void CreateRegisterMapIfNeeded(); diff --git a/contrib/llvm-project/lldb/source/Plugins/ABI/X86/ABIMacOSX_i386.cpp b/contrib/llvm-project/lldb/source/Plugins/ABI/X86/ABIMacOSX_i386.cpp index 461e4af599d3..69adeee4742b 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ABI/X86/ABIMacOSX_i386.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/ABI/X86/ABIMacOSX_i386.cpp @@ -460,16 +460,3 @@ void ABIMacOSX_i386::Initialize() { void ABIMacOSX_i386::Terminate() { PluginManager::UnregisterPlugin(CreateInstance); } - -lldb_private::ConstString ABIMacOSX_i386::GetPluginNameStatic() { - static ConstString g_short_name("abi.macosx-i386"); - return g_short_name; -} - -// PluginInterface protocol - -lldb_private::ConstString ABIMacOSX_i386::GetPluginName() { - return GetPluginNameStatic(); -} - -uint32_t ABIMacOSX_i386::GetPluginVersion() { return 1; } diff --git a/contrib/llvm-project/lldb/source/Plugins/ABI/X86/ABIMacOSX_i386.h b/contrib/llvm-project/lldb/source/Plugins/ABI/X86/ABIMacOSX_i386.h index b8b253144165..462317f17666 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ABI/X86/ABIMacOSX_i386.h +++ b/contrib/llvm-project/lldb/source/Plugins/ABI/X86/ABIMacOSX_i386.h @@ -9,11 +9,11 @@ #ifndef LLDB_SOURCE_PLUGINS_ABI_X86_ABIMACOSX_I386_H #define LLDB_SOURCE_PLUGINS_ABI_X86_ABIMACOSX_I386_H -#include "Plugins/ABI/X86/ABIX86.h" +#include "Plugins/ABI/X86/ABIX86_i386.h" #include "lldb/Core/Value.h" #include "lldb/lldb-private.h" -class ABIMacOSX_i386 : public ABIX86 { +class ABIMacOSX_i386 : public ABIX86_i386 { public: ~ABIMacOSX_i386() override = default; @@ -75,11 +75,9 @@ public: // PluginInterface protocol - static lldb_private::ConstString GetPluginNameStatic(); + static llvm::StringRef GetPluginNameStatic() { return "abi.macosx-i386"; } - lldb_private::ConstString GetPluginName() override; - - uint32_t GetPluginVersion() override; + llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); } protected: lldb::ValueObjectSP @@ -94,7 +92,7 @@ protected: } private: - using ABIX86::ABIX86; // Call CreateInstance instead. + using ABIX86_i386::ABIX86_i386; // Call CreateInstance instead. }; #endif // LLDB_SOURCE_PLUGINS_ABI_X86_ABIMACOSX_I386_H diff --git a/contrib/llvm-project/lldb/source/Plugins/ABI/X86/ABISysV_i386.cpp b/contrib/llvm-project/lldb/source/Plugins/ABI/X86/ABISysV_i386.cpp index 7d2f0a64d679..054e28f5c7a6 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ABI/X86/ABISysV_i386.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/ABI/X86/ABISysV_i386.cpp @@ -714,14 +714,3 @@ void ABISysV_i386::Initialize() { void ABISysV_i386::Terminate() { PluginManager::UnregisterPlugin(CreateInstance); } - -// PluginInterface protocol - -lldb_private::ConstString ABISysV_i386::GetPluginNameStatic() { - static ConstString g_name("sysv-i386"); - return g_name; -} - -lldb_private::ConstString ABISysV_i386::GetPluginName() { - return GetPluginNameStatic(); -} diff --git a/contrib/llvm-project/lldb/source/Plugins/ABI/X86/ABISysV_i386.h b/contrib/llvm-project/lldb/source/Plugins/ABI/X86/ABISysV_i386.h index 1ebb107d36df..a19c8ddb5b64 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ABI/X86/ABISysV_i386.h +++ b/contrib/llvm-project/lldb/source/Plugins/ABI/X86/ABISysV_i386.h @@ -9,10 +9,10 @@ #ifndef LLDB_SOURCE_PLUGINS_ABI_X86_ABISYSV_I386_H #define LLDB_SOURCE_PLUGINS_ABI_X86_ABISYSV_I386_H -#include "Plugins/ABI/X86/ABIX86.h" +#include "Plugins/ABI/X86/ABIX86_i386.h" #include "lldb/lldb-private.h" -class ABISysV_i386 : public ABIX86 { +class ABISysV_i386 : public ABIX86_i386 { public: ~ABISysV_i386() override = default; @@ -83,11 +83,9 @@ public: // PluginInterface protocol - static lldb_private::ConstString GetPluginNameStatic(); + static llvm::StringRef GetPluginNameStatic() { return "sysv-i386"; } - lldb_private::ConstString GetPluginName() override; - - uint32_t GetPluginVersion() override { return 1; } + llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); } protected: lldb::ValueObjectSP @@ -97,7 +95,7 @@ protected: bool RegisterIsCalleeSaved(const lldb_private::RegisterInfo *reg_info); private: - using ABIX86::ABIX86; // Call CreateInstance instead. + using ABIX86_i386::ABIX86_i386; // Call CreateInstance instead. }; #endif // LLDB_SOURCE_PLUGINS_ABI_X86_ABISYSV_I386_H diff --git a/contrib/llvm-project/lldb/source/Plugins/ABI/X86/ABISysV_x86_64.cpp b/contrib/llvm-project/lldb/source/Plugins/ABI/X86/ABISysV_x86_64.cpp index 196b45b3b6da..b51ee5c48515 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ABI/X86/ABISysV_x86_64.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/ABI/X86/ABISysV_x86_64.cpp @@ -933,6 +933,8 @@ uint32_t ABISysV_x86_64::GetGenericNum(llvm::StringRef name) { .Case("rsp", LLDB_REGNUM_GENERIC_SP) .Case("rbp", LLDB_REGNUM_GENERIC_FP) .Case("rflags", LLDB_REGNUM_GENERIC_FLAGS) + // gdbserver uses eflags + .Case("eflags", LLDB_REGNUM_GENERIC_FLAGS) .Case("rdi", LLDB_REGNUM_GENERIC_ARG1) .Case("rsi", LLDB_REGNUM_GENERIC_ARG2) .Case("rdx", LLDB_REGNUM_GENERIC_ARG3) @@ -950,16 +952,3 @@ void ABISysV_x86_64::Initialize() { void ABISysV_x86_64::Terminate() { PluginManager::UnregisterPlugin(CreateInstance); } - -lldb_private::ConstString ABISysV_x86_64::GetPluginNameStatic() { - static ConstString g_name("sysv-x86_64"); - return g_name; -} - -// PluginInterface protocol - -lldb_private::ConstString ABISysV_x86_64::GetPluginName() { - return GetPluginNameStatic(); -} - -uint32_t ABISysV_x86_64::GetPluginVersion() { return 1; } diff --git a/contrib/llvm-project/lldb/source/Plugins/ABI/X86/ABISysV_x86_64.h b/contrib/llvm-project/lldb/source/Plugins/ABI/X86/ABISysV_x86_64.h index 6dce4ce0f012..ce0357dfa331 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ABI/X86/ABISysV_x86_64.h +++ b/contrib/llvm-project/lldb/source/Plugins/ABI/X86/ABISysV_x86_64.h @@ -76,13 +76,10 @@ public: static lldb::ABISP CreateInstance(lldb::ProcessSP process_sp, const lldb_private::ArchSpec &arch); - static lldb_private::ConstString GetPluginNameStatic(); + static llvm::StringRef GetPluginNameStatic() { return "sysv-x86_64"; } // PluginInterface protocol - - lldb_private::ConstString GetPluginName() override; - - uint32_t GetPluginVersion() override; + llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); } protected: void CreateRegisterMapIfNeeded(); diff --git a/contrib/llvm-project/lldb/source/Plugins/ABI/X86/ABIWindows_x86_64.cpp b/contrib/llvm-project/lldb/source/Plugins/ABI/X86/ABIWindows_x86_64.cpp index 6c473c652c5f..5e8f8b16ec1a 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ABI/X86/ABIWindows_x86_64.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/ABI/X86/ABIWindows_x86_64.cpp @@ -806,6 +806,8 @@ uint32_t ABIWindows_x86_64::GetGenericNum(llvm::StringRef reg) { .Case("rsp", LLDB_REGNUM_GENERIC_SP) .Case("rbp", LLDB_REGNUM_GENERIC_FP) .Case("rflags", LLDB_REGNUM_GENERIC_FLAGS) + // gdbserver uses eflags + .Case("eflags", LLDB_REGNUM_GENERIC_FLAGS) .Case("rcx", LLDB_REGNUM_GENERIC_ARG1) .Case("rdx", LLDB_REGNUM_GENERIC_ARG2) .Case("r8", LLDB_REGNUM_GENERIC_ARG3) @@ -821,18 +823,3 @@ void ABIWindows_x86_64::Initialize() { void ABIWindows_x86_64::Terminate() { PluginManager::UnregisterPlugin(CreateInstance); } - -lldb_private::ConstString ABIWindows_x86_64::GetPluginNameStatic() { - static ConstString g_name("windows-x86_64"); - return g_name; -} - -//------------------------------------------------------------------ -// PluginInterface protocol -//------------------------------------------------------------------ - -lldb_private::ConstString ABIWindows_x86_64::GetPluginName() { - return GetPluginNameStatic(); -} - -uint32_t ABIWindows_x86_64::GetPluginVersion() { return 1; } diff --git a/contrib/llvm-project/lldb/source/Plugins/ABI/X86/ABIWindows_x86_64.h b/contrib/llvm-project/lldb/source/Plugins/ABI/X86/ABIWindows_x86_64.h index 89fc6e6ca21f..e74b9126404e 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ABI/X86/ABIWindows_x86_64.h +++ b/contrib/llvm-project/lldb/source/Plugins/ABI/X86/ABIWindows_x86_64.h @@ -67,15 +67,13 @@ public: static lldb::ABISP CreateInstance(lldb::ProcessSP process_sp, const lldb_private::ArchSpec &arch); - static lldb_private::ConstString GetPluginNameStatic(); + static llvm::StringRef GetPluginNameStatic() { return "windows-x86_64"; } //------------------------------------------------------------------ // PluginInterface protocol //------------------------------------------------------------------ - lldb_private::ConstString GetPluginName() override; - - uint32_t GetPluginVersion() override; + llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); } protected: void CreateRegisterMapIfNeeded(); diff --git a/contrib/llvm-project/lldb/source/Plugins/ABI/X86/ABIX86.cpp b/contrib/llvm-project/lldb/source/Plugins/ABI/X86/ABIX86.cpp index 643365f72a79..f717fe596946 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ABI/X86/ABIX86.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/ABI/X86/ABIX86.cpp @@ -1,4 +1,4 @@ -//===-- X86.h -------------------------------------------------------------===// +//===-- ABIX86.cpp --------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -6,7 +6,6 @@ // //===----------------------------------------------------------------------===// -#include "ABIX86.h" #ifdef LLDB_ENABLE_ALL #include "ABIMacOSX_i386.h" #endif // LLDB_ENABLE_ALL @@ -15,7 +14,12 @@ #ifdef LLDB_ENABLE_ALL #include "ABIWindows_x86_64.h" #endif // LLDB_ENABLE_ALL +#include "ABIX86.h" #include "lldb/Core/PluginManager.h" +#include "lldb/Target/Process.h" + +using namespace lldb; +using namespace lldb_private; LLDB_PLUGIN_DEFINE(ABIX86) @@ -41,15 +45,225 @@ void ABIX86::Terminate() { #endif // LLDB_ENABLE_ALL } -uint32_t ABIX86::GetGenericNum(llvm::StringRef name) { - return llvm::StringSwitch<uint32_t>(name) - .Case("eip", LLDB_REGNUM_GENERIC_PC) - .Case("esp", LLDB_REGNUM_GENERIC_SP) - .Case("ebp", LLDB_REGNUM_GENERIC_FP) - .Case("eflags", LLDB_REGNUM_GENERIC_FLAGS) - .Case("edi", LLDB_REGNUM_GENERIC_ARG1) - .Case("esi", LLDB_REGNUM_GENERIC_ARG2) - .Case("edx", LLDB_REGNUM_GENERIC_ARG3) - .Case("ecx", LLDB_REGNUM_GENERIC_ARG4) - .Default(LLDB_INVALID_REGNUM); +namespace { +enum RegKind { + GPR32, + GPR16, + GPR8h, + GPR8, + MM, + YMM_YMMh, + YMM_XMM, + + RegKindCount +}; +} + +struct RegData { + RegKind subreg_kind; + llvm::StringRef subreg_name; + llvm::Optional<uint32_t> base_index; +}; + +static void +addPartialRegisters(std::vector<DynamicRegisterInfo::Register> ®s, + llvm::ArrayRef<RegData *> subregs, uint32_t base_size, + lldb::Encoding encoding, lldb::Format format, + uint32_t subreg_size, uint32_t subreg_offset = 0) { + for (const RegData *subreg : subregs) { + assert(subreg); + uint32_t base_index = subreg->base_index.getValue(); + DynamicRegisterInfo::Register &full_reg = regs[base_index]; + if (full_reg.byte_size != base_size) + continue; + + lldb_private::DynamicRegisterInfo::Register new_reg{ + lldb_private::ConstString(subreg->subreg_name), + lldb_private::ConstString(), + lldb_private::ConstString("supplementary registers"), + subreg_size, + LLDB_INVALID_INDEX32, + encoding, + format, + LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, + {base_index}, + {}, + subreg_offset}; + + addSupplementaryRegister(regs, new_reg); + } +} + +static void +addCombinedRegisters(std::vector<DynamicRegisterInfo::Register> ®s, + llvm::ArrayRef<RegData *> subregs1, + llvm::ArrayRef<RegData *> subregs2, uint32_t base_size, + lldb::Encoding encoding, lldb::Format format) { + for (auto it : llvm::zip(subregs1, subregs2)) { + RegData *regdata1, *regdata2; + std::tie(regdata1, regdata2) = it; + assert(regdata1); + assert(regdata2); + + // verify that we've got matching target registers + if (regdata1->subreg_name != regdata2->subreg_name) + continue; + + uint32_t base_index1 = regdata1->base_index.getValue(); + uint32_t base_index2 = regdata2->base_index.getValue(); + if (regs[base_index1].byte_size != base_size || + regs[base_index2].byte_size != base_size) + continue; + + lldb_private::DynamicRegisterInfo::Register new_reg{ + lldb_private::ConstString(regdata1->subreg_name), + lldb_private::ConstString(), + lldb_private::ConstString("supplementary registers"), + base_size * 2, + LLDB_INVALID_INDEX32, + encoding, + format, + LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, + {base_index1, base_index2}, + {}}; + + addSupplementaryRegister(regs, new_reg); + } +} + +typedef llvm::SmallDenseMap<llvm::StringRef, llvm::SmallVector<RegData, 4>, 64> + BaseRegToRegsMap; + +#define GPRh(l) \ + { \ + is64bit \ + ? BaseRegToRegsMap::value_type("r" l "x", \ + {{GPR32, "e" l "x", llvm::None}, \ + {GPR16, l "x", llvm::None}, \ + {GPR8h, l "h", llvm::None}, \ + {GPR8, l "l", llvm::None}}) \ + : BaseRegToRegsMap::value_type("e" l "x", {{GPR16, l "x", llvm::None}, \ + {GPR8h, l "h", llvm::None}, \ + {GPR8, l "l", llvm::None}}) \ + } + +#define GPR(r16) \ + { \ + is64bit \ + ? BaseRegToRegsMap::value_type("r" r16, {{GPR32, "e" r16, llvm::None}, \ + {GPR16, r16, llvm::None}, \ + {GPR8, r16 "l", llvm::None}}) \ + : BaseRegToRegsMap::value_type("e" r16, {{GPR16, r16, llvm::None}, \ + {GPR8, r16 "l", llvm::None}}) \ + } + +#define GPR64(n) \ + { \ + BaseRegToRegsMap::value_type("r" #n, {{GPR32, "r" #n "d", llvm::None}, \ + {GPR16, "r" #n "w", llvm::None}, \ + {GPR8, "r" #n "l", llvm::None}}) \ + } + +#define STMM(n) \ + { BaseRegToRegsMap::value_type("st" #n, {{MM, "mm" #n, llvm::None}}) } + +#define YMM(n) \ + {BaseRegToRegsMap::value_type("ymm" #n "h", \ + {{YMM_YMMh, "ymm" #n, llvm::None}})}, \ + { \ + BaseRegToRegsMap::value_type("xmm" #n, {{YMM_XMM, "ymm" #n, llvm::None}}) \ + } + +BaseRegToRegsMap makeBaseRegMap(bool is64bit) { + BaseRegToRegsMap out{ + {// GPRs common to amd64 & i386 + GPRh("a"), GPRh("b"), GPRh("c"), GPRh("d"), GPR("si"), GPR("di"), + GPR("bp"), GPR("sp"), + + // ST/MM registers + STMM(0), STMM(1), STMM(2), STMM(3), STMM(4), STMM(5), STMM(6), STMM(7), + + // lower YMM registers (common to amd64 & i386) + YMM(0), YMM(1), YMM(2), YMM(3), YMM(4), YMM(5), YMM(6), YMM(7)}}; + + if (is64bit) { + BaseRegToRegsMap amd64_regs{{// GPRs specific to amd64 + GPR64(8), GPR64(9), GPR64(10), GPR64(11), + GPR64(12), GPR64(13), GPR64(14), GPR64(15), + + // higher YMM registers (specific to amd64) + YMM(8), YMM(9), YMM(10), YMM(11), YMM(12), + YMM(13), YMM(14), YMM(15)}}; + out.insert(amd64_regs.begin(), amd64_regs.end()); + } + + return out; +} + +void ABIX86::AugmentRegisterInfo( + std::vector<DynamicRegisterInfo::Register> ®s) { + MCBasedABI::AugmentRegisterInfo(regs); + + ProcessSP process_sp = GetProcessSP(); + if (!process_sp) + return; + + uint32_t gpr_base_size = + process_sp->GetTarget().GetArchitecture().GetAddressByteSize(); + + // primary map from a base register to its subregisters + BaseRegToRegsMap base_reg_map = makeBaseRegMap(gpr_base_size == 8); + // set used for fast matching of register names to subregisters + llvm::SmallDenseSet<llvm::StringRef, 64> subreg_name_set; + // convenience array providing access to all subregisters of given kind, + // sorted by base register index + std::array<llvm::SmallVector<RegData *, 16>, RegKindCount> subreg_by_kind; + + // prepare the set of all known subregisters + for (const auto &x : base_reg_map) { + for (const auto &subreg : x.second) + subreg_name_set.insert(subreg.subreg_name); + } + + // iterate over all registers + for (const auto &x : llvm::enumerate(regs)) { + llvm::StringRef reg_name = x.value().name.GetStringRef(); + // abort if at least one sub-register is already present + if (llvm::is_contained(subreg_name_set, reg_name)) + return; + + auto found = base_reg_map.find(reg_name); + if (found == base_reg_map.end()) + continue; + + for (auto &subreg : found->second) { + // fill in base register indices + subreg.base_index = x.index(); + // fill subreg_by_kind map-array + subreg_by_kind[static_cast<size_t>(subreg.subreg_kind)].push_back( + &subreg); + } + } + + // now add registers by kind + addPartialRegisters(regs, subreg_by_kind[GPR32], gpr_base_size, eEncodingUint, + eFormatHex, 4); + addPartialRegisters(regs, subreg_by_kind[GPR16], gpr_base_size, eEncodingUint, + eFormatHex, 2); + addPartialRegisters(regs, subreg_by_kind[GPR8h], gpr_base_size, eEncodingUint, + eFormatHex, 1, 1); + addPartialRegisters(regs, subreg_by_kind[GPR8], gpr_base_size, eEncodingUint, + eFormatHex, 1); + + addPartialRegisters(regs, subreg_by_kind[MM], 10, eEncodingUint, eFormatHex, + 8); + + addCombinedRegisters(regs, subreg_by_kind[YMM_XMM], subreg_by_kind[YMM_YMMh], + 16, eEncodingVector, eFormatVectorOfUInt8); } diff --git a/contrib/llvm-project/lldb/source/Plugins/ABI/X86/ABIX86.h b/contrib/llvm-project/lldb/source/Plugins/ABI/X86/ABIX86.h index 22521cacf180..1114084fbc5d 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ABI/X86/ABIX86.h +++ b/contrib/llvm-project/lldb/source/Plugins/ABI/X86/ABIX86.h @@ -1,4 +1,4 @@ -//===-- X86.h ---------------------------------------------------*- C++ -*-===// +//===-- ABIX86.h ------------------------------------------------*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -10,15 +10,19 @@ #define LLDB_SOURCE_PLUGINS_ABI_X86_ABIX86_H #include "lldb/Target/ABI.h" +#include "lldb/lldb-private.h" class ABIX86 : public lldb_private::MCBasedABI { public: static void Initialize(); static void Terminate(); - uint32_t GetGenericNum(llvm::StringRef name) override; +protected: + void AugmentRegisterInfo( + std::vector<lldb_private::DynamicRegisterInfo::Register> ®s) override; private: using lldb_private::MCBasedABI::MCBasedABI; }; + #endif diff --git a/contrib/llvm-project/lldb/source/Plugins/ABI/X86/ABIX86_64.h b/contrib/llvm-project/lldb/source/Plugins/ABI/X86/ABIX86_64.h index e65c2d97d897..8fc98507adee 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ABI/X86/ABIX86_64.h +++ b/contrib/llvm-project/lldb/source/Plugins/ABI/X86/ABIX86_64.h @@ -9,10 +9,9 @@ #ifndef LLDB_SOURCE_PLUGINS_ABI_X86_ABIX86_64_H #define LLDB_SOURCE_PLUGINS_ABI_X86_ABIX86_64_H -#include "lldb/Target/ABI.h" -#include "lldb/lldb-private.h" +#include "Plugins/ABI/X86/ABIX86.h" -class ABIX86_64 : public lldb_private::MCBasedABI { +class ABIX86_64 : public ABIX86 { protected: std::string GetMCName(std::string name) override { MapRegisterName(name, "stmm", "st"); @@ -20,7 +19,7 @@ protected: } private: - using lldb_private::MCBasedABI::MCBasedABI; + using ABIX86::ABIX86; }; #endif // LLDB_SOURCE_PLUGINS_ABI_X86_ABIX86_64_H diff --git a/contrib/llvm-project/lldb/source/Plugins/ABI/X86/ABIX86_i386.cpp b/contrib/llvm-project/lldb/source/Plugins/ABI/X86/ABIX86_i386.cpp new file mode 100644 index 000000000000..e376f0eb2bc7 --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/ABI/X86/ABIX86_i386.cpp @@ -0,0 +1,22 @@ +//===-- ABIX86_i386.cpp ---------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "ABIX86_i386.h" + +uint32_t ABIX86_i386::GetGenericNum(llvm::StringRef name) { + return llvm::StringSwitch<uint32_t>(name) + .Case("eip", LLDB_REGNUM_GENERIC_PC) + .Case("esp", LLDB_REGNUM_GENERIC_SP) + .Case("ebp", LLDB_REGNUM_GENERIC_FP) + .Case("eflags", LLDB_REGNUM_GENERIC_FLAGS) + .Case("edi", LLDB_REGNUM_GENERIC_ARG1) + .Case("esi", LLDB_REGNUM_GENERIC_ARG2) + .Case("edx", LLDB_REGNUM_GENERIC_ARG3) + .Case("ecx", LLDB_REGNUM_GENERIC_ARG4) + .Default(LLDB_INVALID_REGNUM); +} diff --git a/contrib/llvm-project/lldb/source/Plugins/ABI/X86/ABIX86_i386.h b/contrib/llvm-project/lldb/source/Plugins/ABI/X86/ABIX86_i386.h new file mode 100644 index 000000000000..cb3baa5150fc --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/ABI/X86/ABIX86_i386.h @@ -0,0 +1,22 @@ +//===-- ABIX86_i386.h -------------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_SOURCE_PLUGINS_ABI_X86_ABIX86_I386_H +#define LLDB_SOURCE_PLUGINS_ABI_X86_ABIX86_I386_H + +#include "Plugins/ABI/X86/ABIX86.h" + +class ABIX86_i386 : public ABIX86 { +public: + uint32_t GetGenericNum(llvm::StringRef name) override; + +private: + using ABIX86::ABIX86; +}; + +#endif diff --git a/contrib/llvm-project/lldb/source/Plugins/Architecture/AArch64/ArchitectureAArch64.cpp b/contrib/llvm-project/lldb/source/Plugins/Architecture/AArch64/ArchitectureAArch64.cpp index 9994cc293d6a..1b2b41ee8758 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Architecture/AArch64/ArchitectureAArch64.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Architecture/AArch64/ArchitectureAArch64.cpp @@ -15,10 +15,6 @@ using namespace lldb; LLDB_PLUGIN_DEFINE(ArchitectureAArch64) -ConstString ArchitectureAArch64::GetPluginNameStatic() { - return ConstString("aarch64"); -} - void ArchitectureAArch64::Initialize() { PluginManager::RegisterPlugin(GetPluginNameStatic(), "AArch64-specific algorithms", @@ -38,8 +34,3 @@ ArchitectureAArch64::Create(const ArchSpec &arch) { } return std::unique_ptr<Architecture>(new ArchitectureAArch64()); } - -ConstString ArchitectureAArch64::GetPluginName() { - return GetPluginNameStatic(); -} -uint32_t ArchitectureAArch64::GetPluginVersion() { return 1; } diff --git a/contrib/llvm-project/lldb/source/Plugins/Architecture/AArch64/ArchitectureAArch64.h b/contrib/llvm-project/lldb/source/Plugins/Architecture/AArch64/ArchitectureAArch64.h index 775478cc9338..e1b8558e1cda 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Architecture/AArch64/ArchitectureAArch64.h +++ b/contrib/llvm-project/lldb/source/Plugins/Architecture/AArch64/ArchitectureAArch64.h @@ -16,12 +16,11 @@ namespace lldb_private { class ArchitectureAArch64 : public Architecture { public: - static ConstString GetPluginNameStatic(); + static llvm::StringRef GetPluginNameStatic() { return "aarch64"; } static void Initialize(); static void Terminate(); - ConstString GetPluginName() override; - uint32_t GetPluginVersion() override; + llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); } void OverrideStopInfo(Thread &thread) const override{}; diff --git a/contrib/llvm-project/lldb/source/Plugins/Architecture/Arm/ArchitectureArm.cpp b/contrib/llvm-project/lldb/source/Plugins/Architecture/Arm/ArchitectureArm.cpp index 58c7cbb4530a..bb44675e842e 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Architecture/Arm/ArchitectureArm.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Architecture/Arm/ArchitectureArm.cpp @@ -19,10 +19,6 @@ using namespace lldb; LLDB_PLUGIN_DEFINE(ArchitectureArm) -ConstString ArchitectureArm::GetPluginNameStatic() { - return ConstString("arm"); -} - void ArchitectureArm::Initialize() { PluginManager::RegisterPlugin(GetPluginNameStatic(), "Arm-specific algorithms", @@ -39,9 +35,6 @@ std::unique_ptr<Architecture> ArchitectureArm::Create(const ArchSpec &arch) { return std::unique_ptr<Architecture>(new ArchitectureArm()); } -ConstString ArchitectureArm::GetPluginName() { return GetPluginNameStatic(); } -uint32_t ArchitectureArm::GetPluginVersion() { return 1; } - void ArchitectureArm::OverrideStopInfo(Thread &thread) const { // We need to check if we are stopped in Thumb mode in a IT instruction and // detect if the condition doesn't pass. If this is the case it means we diff --git a/contrib/llvm-project/lldb/source/Plugins/Architecture/Arm/ArchitectureArm.h b/contrib/llvm-project/lldb/source/Plugins/Architecture/Arm/ArchitectureArm.h index 36b79c7c01a1..f579d6b62505 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Architecture/Arm/ArchitectureArm.h +++ b/contrib/llvm-project/lldb/source/Plugins/Architecture/Arm/ArchitectureArm.h @@ -15,12 +15,11 @@ namespace lldb_private { class ArchitectureArm : public Architecture { public: - static ConstString GetPluginNameStatic(); + static llvm::StringRef GetPluginNameStatic() { return "arm"; } static void Initialize(); static void Terminate(); - ConstString GetPluginName() override; - uint32_t GetPluginVersion() override; + llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); } void OverrideStopInfo(Thread &thread) const override; diff --git a/contrib/llvm-project/lldb/source/Plugins/Architecture/Mips/ArchitectureMips.cpp b/contrib/llvm-project/lldb/source/Plugins/Architecture/Mips/ArchitectureMips.cpp index 757c91570009..865c72fed61c 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Architecture/Mips/ArchitectureMips.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Architecture/Mips/ArchitectureMips.cpp @@ -23,10 +23,6 @@ using namespace lldb; LLDB_PLUGIN_DEFINE(ArchitectureMips) -ConstString ArchitectureMips::GetPluginNameStatic() { - return ConstString("mips"); -} - void ArchitectureMips::Initialize() { PluginManager::RegisterPlugin(GetPluginNameStatic(), "Mips-specific algorithms", @@ -42,9 +38,6 @@ std::unique_ptr<Architecture> ArchitectureMips::Create(const ArchSpec &arch) { std::unique_ptr<Architecture>(new ArchitectureMips(arch)) : nullptr; } -ConstString ArchitectureMips::GetPluginName() { return GetPluginNameStatic(); } -uint32_t ArchitectureMips::GetPluginVersion() { return 1; } - addr_t ArchitectureMips::GetCallableLoadAddress(addr_t code_addr, AddressClass addr_class) const { bool is_alternate_isa = false; diff --git a/contrib/llvm-project/lldb/source/Plugins/Architecture/Mips/ArchitectureMips.h b/contrib/llvm-project/lldb/source/Plugins/Architecture/Mips/ArchitectureMips.h index 71ee60184b69..9513a10b5965 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Architecture/Mips/ArchitectureMips.h +++ b/contrib/llvm-project/lldb/source/Plugins/Architecture/Mips/ArchitectureMips.h @@ -16,12 +16,11 @@ namespace lldb_private { class ArchitectureMips : public Architecture { public: - static ConstString GetPluginNameStatic(); + static llvm::StringRef GetPluginNameStatic() { return "mips"; } static void Initialize(); static void Terminate(); - ConstString GetPluginName() override; - uint32_t GetPluginVersion() override; + llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); } void OverrideStopInfo(Thread &thread) const override {} diff --git a/contrib/llvm-project/lldb/source/Plugins/Architecture/PPC64/ArchitecturePPC64.cpp b/contrib/llvm-project/lldb/source/Plugins/Architecture/PPC64/ArchitecturePPC64.cpp index 94301ecf052c..b8fac55e41da 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Architecture/PPC64/ArchitecturePPC64.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Architecture/PPC64/ArchitecturePPC64.cpp @@ -22,10 +22,6 @@ using namespace lldb; LLDB_PLUGIN_DEFINE(ArchitecturePPC64) -ConstString ArchitecturePPC64::GetPluginNameStatic() { - return ConstString("ppc64"); -} - void ArchitecturePPC64::Initialize() { PluginManager::RegisterPlugin(GetPluginNameStatic(), "PPC64-specific algorithms", @@ -43,9 +39,6 @@ std::unique_ptr<Architecture> ArchitecturePPC64::Create(const ArchSpec &arch) { return nullptr; } -ConstString ArchitecturePPC64::GetPluginName() { return GetPluginNameStatic(); } -uint32_t ArchitecturePPC64::GetPluginVersion() { return 1; } - static int32_t GetLocalEntryOffset(const Symbol &sym) { unsigned char other = sym.GetFlags() >> 8 & 0xFF; return llvm::ELF::decodePPC64LocalEntryOffset(other); diff --git a/contrib/llvm-project/lldb/source/Plugins/Architecture/PPC64/ArchitecturePPC64.h b/contrib/llvm-project/lldb/source/Plugins/Architecture/PPC64/ArchitecturePPC64.h index 25210d37e53a..80f7f27b54cc 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Architecture/PPC64/ArchitecturePPC64.h +++ b/contrib/llvm-project/lldb/source/Plugins/Architecture/PPC64/ArchitecturePPC64.h @@ -15,12 +15,11 @@ namespace lldb_private { class ArchitecturePPC64 : public Architecture { public: - static ConstString GetPluginNameStatic(); + static llvm::StringRef GetPluginNameStatic() { return "ppc64"; } static void Initialize(); static void Terminate(); - ConstString GetPluginName() override; - uint32_t GetPluginVersion() override; + llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); } void OverrideStopInfo(Thread &thread) const override {} diff --git a/contrib/llvm-project/lldb/source/Plugins/Disassembler/LLVMC/DisassemblerLLVMC.cpp b/contrib/llvm-project/lldb/source/Plugins/Disassembler/LLVMC/DisassemblerLLVMC.cpp index 7cd505d0ed29..2cf32bdd3800 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Disassembler/LLVMC/DisassemblerLLVMC.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Disassembler/LLVMC/DisassemblerLLVMC.cpp @@ -21,9 +21,9 @@ #include "llvm/MC/MCRegisterInfo.h" #include "llvm/MC/MCSubtargetInfo.h" #include "llvm/MC/MCTargetOptions.h" +#include "llvm/MC/TargetRegistry.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/ScopedPrinter.h" -#include "llvm/Support/TargetRegistry.h" #include "llvm/Support/TargetSelect.h" #include "lldb/Core/Address.h" @@ -61,6 +61,8 @@ public: bool CanBranch(llvm::MCInst &mc_inst) const; bool HasDelaySlot(llvm::MCInst &mc_inst) const; bool IsCall(llvm::MCInst &mc_inst) const; + bool IsLoad(llvm::MCInst &mc_inst) const; + bool IsAuthenticated(llvm::MCInst &mc_inst) const; private: MCDisasmInstance(std::unique_ptr<llvm::MCInstrInfo> &&instr_info_up, @@ -102,6 +104,16 @@ public: return m_has_delay_slot; } + bool IsLoad() override { + VisitInstruction(); + return m_is_load; + } + + bool IsAuthenticated() override { + VisitInstruction(); + return m_is_authenticated; + } + DisassemblerLLVMC::MCDisasmInstance *GetDisasmToUse(bool &is_alternate_isa) { DisassemblerScope disasm(*this); return GetDisasmToUse(is_alternate_isa, disasm); @@ -817,9 +829,13 @@ protected: // - Might branch // - Does not have a delay slot // - Is not a call + // - Is not a load + // - Is not an authenticated instruction bool m_does_branch = true; bool m_has_delay_slot = false; bool m_is_call = false; + bool m_is_load = false; + bool m_is_authenticated = false; void VisitInstruction() { if (m_has_visited_instruction) @@ -849,6 +865,8 @@ protected: m_does_branch = mc_disasm_ptr->CanBranch(inst); m_has_delay_slot = mc_disasm_ptr->HasDelaySlot(inst); m_is_call = mc_disasm_ptr->IsCall(inst); + m_is_load = mc_disasm_ptr->IsLoad(inst); + m_is_authenticated = mc_disasm_ptr->IsAuthenticated(inst); } private: @@ -1027,10 +1045,32 @@ bool DisassemblerLLVMC::MCDisasmInstance::IsCall(llvm::MCInst &mc_inst) const { return m_instr_info_up->get(mc_inst.getOpcode()).isCall(); } +bool DisassemblerLLVMC::MCDisasmInstance::IsLoad(llvm::MCInst &mc_inst) const { + return m_instr_info_up->get(mc_inst.getOpcode()).mayLoad(); +} + +bool DisassemblerLLVMC::MCDisasmInstance::IsAuthenticated( + llvm::MCInst &mc_inst) const { + auto InstrDesc = m_instr_info_up->get(mc_inst.getOpcode()); + + // Treat software auth traps (brk 0xc470 + aut key, where 0x70 == 'p', 0xc4 + // == 'a' + 'c') as authenticated instructions for reporting purposes, in + // addition to the standard authenticated instructions specified in ARMv8.3. + bool IsBrkC47x = false; + if (InstrDesc.isTrap() && mc_inst.getNumOperands() == 1) { + const llvm::MCOperand &Op0 = mc_inst.getOperand(0); + if (Op0.isImm() && Op0.getImm() >= 0xc470 && Op0.getImm() <= 0xc474) + IsBrkC47x = true; + } + + return InstrDesc.isAuthenticated() || IsBrkC47x; +} + DisassemblerLLVMC::DisassemblerLLVMC(const ArchSpec &arch, const char *flavor_string) : Disassembler(arch, flavor_string), m_exe_ctx(nullptr), m_inst(nullptr), - m_data_from_file(false) { + m_data_from_file(false), m_adrp_address(LLDB_INVALID_ADDRESS), + m_adrp_insn() { if (!FlavorValidForArchSpec(arch, m_flavor.c_str())) { m_flavor.assign("default"); } @@ -1255,11 +1295,6 @@ void DisassemblerLLVMC::Terminate() { PluginManager::UnregisterPlugin(CreateInstance); } -ConstString DisassemblerLLVMC::GetPluginNameStatic() { - static ConstString g_name("llvm-mc"); - return g_name; -} - int DisassemblerLLVMC::OpInfoCallback(void *disassembler, uint64_t pc, uint64_t offset, uint64_t size, int tag_type, void *tag_bug) { @@ -1310,6 +1345,46 @@ const char *DisassemblerLLVMC::SymbolLookup(uint64_t value, uint64_t *type_ptr, Target *target = m_exe_ctx ? m_exe_ctx->GetTargetPtr() : nullptr; Address value_so_addr; Address pc_so_addr; + if (target->GetArchitecture().GetMachine() == llvm::Triple::aarch64 || + target->GetArchitecture().GetMachine() == llvm::Triple::aarch64_be || + target->GetArchitecture().GetMachine() == llvm::Triple::aarch64_32) { + if (*type_ptr == LLVMDisassembler_ReferenceType_In_ARM64_ADRP) { + m_adrp_address = pc; + m_adrp_insn = value; + *name = nullptr; + *type_ptr = LLVMDisassembler_ReferenceType_InOut_None; + return nullptr; + } + // If this instruction is an ADD and + // the previous instruction was an ADRP and + // the ADRP's register and this ADD's register are the same, + // then this is a pc-relative address calculation. + if (*type_ptr == LLVMDisassembler_ReferenceType_In_ARM64_ADDXri && + m_adrp_insn.hasValue() && m_adrp_address == pc - 4 && + (m_adrp_insn.getValue() & 0x1f) == ((value >> 5) & 0x1f)) { + uint32_t addxri_inst; + uint64_t adrp_imm, addxri_imm; + // Get immlo and immhi bits, OR them together to get the ADRP imm + // value. + adrp_imm = ((m_adrp_insn.getValue() & 0x00ffffe0) >> 3) | + ((m_adrp_insn.getValue() >> 29) & 0x3); + // if high bit of immhi after right-shifting set, sign extend + if (adrp_imm & (1ULL << 20)) + adrp_imm |= ~((1ULL << 21) - 1); + + addxri_inst = value; + addxri_imm = (addxri_inst >> 10) & 0xfff; + // check if 'sh' bit is set, shift imm value up if so + // (this would make no sense, ADRP already gave us this part) + if ((addxri_inst >> (12 + 5 + 5)) & 1) + addxri_imm <<= 12; + value = (m_adrp_address & 0xfffffffffffff000LL) + (adrp_imm << 12) + + addxri_imm; + } + m_adrp_address = LLDB_INVALID_ADDRESS; + m_adrp_insn.reset(); + } + if (m_inst->UsingFileAddress()) { ModuleSP module_sp(m_inst->GetAddress().GetModule()); if (module_sp) { @@ -1371,12 +1446,13 @@ const char *DisassemblerLLVMC::SymbolLookup(uint64_t value, uint64_t *type_ptr, } } + // TODO: llvm-objdump sets the type_ptr to the + // LLVMDisassembler_ReferenceType_Out_* values + // based on where value_so_addr is pointing, with + // Mach-O specific augmentations in MachODump.cpp. e.g. + // see what AArch64ExternalSymbolizer::tryAddingSymbolicOperand + // handles. *type_ptr = LLVMDisassembler_ReferenceType_InOut_None; *name = nullptr; return nullptr; } - -// PluginInterface protocol -ConstString DisassemblerLLVMC::GetPluginName() { return GetPluginNameStatic(); } - -uint32_t DisassemblerLLVMC::GetPluginVersion() { return 1; } diff --git a/contrib/llvm-project/lldb/source/Plugins/Disassembler/LLVMC/DisassemblerLLVMC.h b/contrib/llvm-project/lldb/source/Plugins/Disassembler/LLVMC/DisassemblerLLVMC.h index 9b3741bdd18f..5d0204caaa9a 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Disassembler/LLVMC/DisassemblerLLVMC.h +++ b/contrib/llvm-project/lldb/source/Plugins/Disassembler/LLVMC/DisassemblerLLVMC.h @@ -16,6 +16,7 @@ #include "lldb/Core/Address.h" #include "lldb/Core/Disassembler.h" #include "lldb/Core/PluginManager.h" +#include "llvm/ADT/Optional.h" class InstructionLLVMC; @@ -31,7 +32,7 @@ public: static void Terminate(); - static lldb_private::ConstString GetPluginNameStatic(); + static llvm::StringRef GetPluginNameStatic() { return "llvm-mc"; } static lldb_private::Disassembler * CreateInstance(const lldb_private::ArchSpec &arch, const char *flavor); @@ -42,9 +43,7 @@ public: bool append, bool data_from_file) override; // PluginInterface protocol - lldb_private::ConstString GetPluginName() override; - - uint32_t GetPluginVersion() override; + llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); } protected: friend class InstructionLLVMC; @@ -73,6 +72,12 @@ protected: InstructionLLVMC *m_inst; std::mutex m_mutex; bool m_data_from_file; + // Save the AArch64 ADRP instruction word and address it was at, + // in case the next instruction is an ADD to the same register; + // this is a pc-relative address calculation and we need both + // parts to calculate the symbolication. + lldb::addr_t m_adrp_address; + llvm::Optional<uint32_t> m_adrp_insn; // Since we need to make two actual MC Disassemblers for ARM (ARM & THUMB), // and there's a bit of goo to set up and own in the MC disassembler world, diff --git a/contrib/llvm-project/lldb/source/Plugins/DynamicLoader/Hexagon-DYLD/DynamicLoaderHexagonDYLD.cpp b/contrib/llvm-project/lldb/source/Plugins/DynamicLoader/Hexagon-DYLD/DynamicLoaderHexagonDYLD.cpp index fe86b2929073..82c50a32594b 100644 --- a/contrib/llvm-project/lldb/source/Plugins/DynamicLoader/Hexagon-DYLD/DynamicLoaderHexagonDYLD.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/DynamicLoader/Hexagon-DYLD/DynamicLoaderHexagonDYLD.cpp @@ -78,22 +78,11 @@ void DynamicLoaderHexagonDYLD::Initialize() { void DynamicLoaderHexagonDYLD::Terminate() {} -lldb_private::ConstString DynamicLoaderHexagonDYLD::GetPluginName() { - return GetPluginNameStatic(); -} - -lldb_private::ConstString DynamicLoaderHexagonDYLD::GetPluginNameStatic() { - static ConstString g_name("hexagon-dyld"); - return g_name; -} - -const char *DynamicLoaderHexagonDYLD::GetPluginDescriptionStatic() { +llvm::StringRef DynamicLoaderHexagonDYLD::GetPluginDescriptionStatic() { return "Dynamic loader plug-in that watches for shared library " "loads/unloads in Hexagon processes."; } -uint32_t DynamicLoaderHexagonDYLD::GetPluginVersion() { return 1; } - DynamicLoader *DynamicLoaderHexagonDYLD::CreateInstance(Process *process, bool force) { bool create = force; diff --git a/contrib/llvm-project/lldb/source/Plugins/DynamicLoader/Hexagon-DYLD/DynamicLoaderHexagonDYLD.h b/contrib/llvm-project/lldb/source/Plugins/DynamicLoader/Hexagon-DYLD/DynamicLoaderHexagonDYLD.h index 2570e003fd6a..54711f5e6bb3 100644 --- a/contrib/llvm-project/lldb/source/Plugins/DynamicLoader/Hexagon-DYLD/DynamicLoaderHexagonDYLD.h +++ b/contrib/llvm-project/lldb/source/Plugins/DynamicLoader/Hexagon-DYLD/DynamicLoaderHexagonDYLD.h @@ -24,9 +24,9 @@ public: static void Terminate(); - static lldb_private::ConstString GetPluginNameStatic(); + static llvm::StringRef GetPluginNameStatic() { return "hexagon-dyld"; } - static const char *GetPluginDescriptionStatic(); + static llvm::StringRef GetPluginDescriptionStatic(); static lldb_private::DynamicLoader * CreateInstance(lldb_private::Process *process, bool force); @@ -47,9 +47,7 @@ public: lldb::addr_t tls_file_addr) override; // PluginInterface protocol - lldb_private::ConstString GetPluginName() override; - - uint32_t GetPluginVersion() override; + llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); } protected: /// Runtime linker rendezvous structure. diff --git a/contrib/llvm-project/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.cpp b/contrib/llvm-project/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.cpp index 866acbddbdc8..7e80dc28e56b 100644 --- a/contrib/llvm-project/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.cpp @@ -24,28 +24,35 @@ using namespace lldb; using namespace lldb_private; -/// Locates the address of the rendezvous structure. Returns the address on -/// success and LLDB_INVALID_ADDRESS on failure. -static addr_t ResolveRendezvousAddress(Process *process) { +DYLDRendezvous::DYLDRendezvous(Process *process) + : m_process(process), m_rendezvous_addr(LLDB_INVALID_ADDRESS), + m_executable_interpreter(false), m_current(), m_previous(), + m_loaded_modules(), m_soentries(), m_added_soentries(), + m_removed_soentries() { + m_thread_info.valid = false; + UpdateExecutablePath(); +} + +addr_t DYLDRendezvous::ResolveRendezvousAddress() { Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER)); addr_t info_location; addr_t info_addr; Status error; - if (!process) { + if (!m_process) { LLDB_LOGF(log, "%s null process provided", __FUNCTION__); return LLDB_INVALID_ADDRESS; } // Try to get it from our process. This might be a remote process and might // grab it via some remote-specific mechanism. - info_location = process->GetImageInfoAddress(); + info_location = m_process->GetImageInfoAddress(); LLDB_LOGF(log, "%s info_location = 0x%" PRIx64, __FUNCTION__, info_location); // If the process fails to return an address, fall back to seeing if the // local object file can help us find it. if (info_location == LLDB_INVALID_ADDRESS) { - Target *target = &process->GetTarget(); + Target *target = &m_process->GetTarget(); if (target) { ObjectFile *obj_file = target->GetExecutableModule()->GetObjectFile(); Address addr = obj_file->GetImageInfoAddress(target); @@ -56,6 +63,20 @@ static addr_t ResolveRendezvousAddress(Process *process) { "%s resolved via direct object file approach to 0x%" PRIx64, __FUNCTION__, info_location); } else { + const Symbol *_r_debug = + target->GetExecutableModule()->FindFirstSymbolWithNameAndType( + ConstString("_r_debug")); + if (_r_debug) { + info_addr = _r_debug->GetAddress().GetLoadAddress(target); + if (info_addr != LLDB_INVALID_ADDRESS) { + LLDB_LOGF(log, + "%s resolved by finding symbol '_r_debug' whose value is " + "0x%" PRIx64, + __FUNCTION__, info_addr); + m_executable_interpreter = true; + return info_addr; + } + } LLDB_LOGF(log, "%s FAILED - direct object file approach did not yield a " "valid address", @@ -70,9 +91,9 @@ static addr_t ResolveRendezvousAddress(Process *process) { } LLDB_LOGF(log, "%s reading pointer (%" PRIu32 " bytes) from 0x%" PRIx64, - __FUNCTION__, process->GetAddressByteSize(), info_location); + __FUNCTION__, m_process->GetAddressByteSize(), info_location); - info_addr = process->ReadPointerFromMemory(info_location, error); + info_addr = m_process->ReadPointerFromMemory(info_location, error); if (error.Fail()) { LLDB_LOGF(log, "%s FAILED - could not read from the info location: %s", __FUNCTION__, error.AsCString()); @@ -90,14 +111,6 @@ static addr_t ResolveRendezvousAddress(Process *process) { return info_addr; } -DYLDRendezvous::DYLDRendezvous(Process *process) - : m_process(process), m_rendezvous_addr(LLDB_INVALID_ADDRESS), m_current(), - m_previous(), m_loaded_modules(), m_soentries(), m_added_soentries(), - m_removed_soentries() { - m_thread_info.valid = false; - UpdateExecutablePath(); -} - void DYLDRendezvous::UpdateExecutablePath() { if (m_process) { Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER)); @@ -132,7 +145,8 @@ bool DYLDRendezvous::Resolve() { __FUNCTION__, uint64_t(address_size), uint64_t(padding)); if (m_rendezvous_addr == LLDB_INVALID_ADDRESS) - cursor = info_addr = ResolveRendezvousAddress(m_process); + cursor = info_addr = + ResolveRendezvousAddress(); else cursor = info_addr = m_rendezvous_addr; LLDB_LOGF(log, "DYLDRendezvous::%s cursor = 0x%" PRIx64, __FUNCTION__, @@ -296,8 +310,10 @@ bool DYLDRendezvous::SaveSOEntriesFromRemote( return false; // Only add shared libraries and not the executable. - if (!SOEntryIsMainExecutable(entry)) + if (!SOEntryIsMainExecutable(entry)) { + UpdateFileSpecIfNecessary(entry); m_soentries.push_back(entry); + } } m_loaded_modules = module_list; @@ -324,6 +340,7 @@ bool DYLDRendezvous::AddSOEntriesFromRemote( // Only add shared libraries and not the executable. if (!SOEntryIsMainExecutable(entry)) { + UpdateFileSpecIfNecessary(entry); m_soentries.push_back(entry); m_added_soentries.push_back(entry); } @@ -383,6 +400,8 @@ bool DYLDRendezvous::AddSOEntries() { if (SOEntryIsMainExecutable(entry)) continue; + UpdateFileSpecIfNecessary(entry); + pos = std::find(m_soentries.begin(), m_soentries.end(), entry); if (pos == m_soentries.end()) { m_soentries.push_back(entry); @@ -424,6 +443,10 @@ bool DYLDRendezvous::SOEntryIsMainExecutable(const SOEntry &entry) { case llvm::Triple::Linux: if (triple.isAndroid()) return entry.file_spec == m_exe_file_spec; + // If we are debugging ld.so, then all SOEntries should be treated as + // libraries, including the "main" one (denoted by an empty string). + if (!entry.file_spec && m_executable_interpreter) + return false; return !entry.file_spec; default: return false; @@ -447,6 +470,8 @@ bool DYLDRendezvous::TakeSnapshot(SOEntryList &entry_list) { if (SOEntryIsMainExecutable(entry)) continue; + UpdateFileSpecIfNecessary(entry); + entry_list.push_back(entry); } @@ -512,6 +537,19 @@ void DYLDRendezvous::UpdateBaseAddrIfNecessary(SOEntry &entry, } } +void DYLDRendezvous::UpdateFileSpecIfNecessary(SOEntry &entry) { + // Updates filename if empty. It is useful while debugging ld.so, + // when the link map returns empty string for the main executable. + if (!entry.file_spec) { + MemoryRegionInfo region; + Status region_status = + m_process->GetMemoryRegionInfo(entry.dyn_addr, region); + if (!region.GetName().IsEmpty()) + entry.file_spec.SetFile(region.GetName().AsCString(), + FileSpec::Style::native); + } +} + bool DYLDRendezvous::ReadSOEntryFromMemory(lldb::addr_t addr, SOEntry &entry) { entry.clear(); diff --git a/contrib/llvm-project/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.h b/contrib/llvm-project/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.h index 5775f5a730cd..04d3e665f859 100644 --- a/contrib/llvm-project/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.h +++ b/contrib/llvm-project/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.h @@ -47,6 +47,12 @@ class DYLDRendezvous { Rendezvous() = default; }; + /// Locates the address of the rendezvous structure. It updates + /// m_executable_interpreter if address is extracted from _r_debug. + /// + /// \returns address on success and LLDB_INVALID_ADDRESS on failure. + lldb::addr_t ResolveRendezvousAddress(); + public: // Various metadata supplied by the inferior's threading library to describe // the per-thread state. @@ -183,6 +189,9 @@ protected: /// Location of the r_debug structure in the inferiors address space. lldb::addr_t m_rendezvous_addr; + // True if the main program is the dynamic linker/loader/program interpreter. + bool m_executable_interpreter; + /// Current and previous snapshots of the rendezvous structure. Rendezvous m_current; Rendezvous m_previous; @@ -246,6 +255,8 @@ protected: void UpdateBaseAddrIfNecessary(SOEntry &entry, std::string const &file_path); + void UpdateFileSpecIfNecessary(SOEntry &entry); + bool SOEntryIsMainExecutable(const SOEntry &entry); /// Reads the current list of shared objects according to the link map diff --git a/contrib/llvm-project/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp b/contrib/llvm-project/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp index 160faa74af23..d9cbcce22c52 100644 --- a/contrib/llvm-project/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp @@ -38,22 +38,11 @@ void DynamicLoaderPOSIXDYLD::Initialize() { void DynamicLoaderPOSIXDYLD::Terminate() {} -lldb_private::ConstString DynamicLoaderPOSIXDYLD::GetPluginName() { - return GetPluginNameStatic(); -} - -lldb_private::ConstString DynamicLoaderPOSIXDYLD::GetPluginNameStatic() { - static ConstString g_name("linux-dyld"); - return g_name; -} - -const char *DynamicLoaderPOSIXDYLD::GetPluginDescriptionStatic() { +llvm::StringRef DynamicLoaderPOSIXDYLD::GetPluginDescriptionStatic() { return "Dynamic loader plug-in that watches for shared library " "loads/unloads in POSIX processes."; } -uint32_t DynamicLoaderPOSIXDYLD::GetPluginVersion() { return 1; } - DynamicLoader *DynamicLoaderPOSIXDYLD::CreateInstance(Process *process, bool force) { bool create = force; @@ -333,28 +322,37 @@ bool DynamicLoaderPOSIXDYLD::SetRendezvousBreakpoint() { LLDB_LOG(log, "Rendezvous structure is not set up yet. " "Trying to locate rendezvous breakpoint in the interpreter " "by symbol name."); - ModuleSP interpreter = LoadInterpreterModule(); - if (!interpreter) { - LLDB_LOG(log, "Can't find interpreter, rendezvous breakpoint isn't set."); - return false; - } - - // Function names from different dynamic loaders that are known to be used - // as rendezvous between the loader and debuggers. + // Function names from different dynamic loaders that are known to be + // used as rendezvous between the loader and debuggers. static std::vector<std::string> DebugStateCandidates{ "_dl_debug_state", "rtld_db_dlactivity", "__dl_rtld_db_dlactivity", "r_debug_state", "_r_debug_state", "_rtld_debug_state", }; - FileSpecList containingModules; - containingModules.Append(interpreter->GetFileSpec()); - dyld_break = target.CreateBreakpoint( - &containingModules, nullptr /* containingSourceFiles */, - DebugStateCandidates, eFunctionNameTypeFull, eLanguageTypeC, - 0, /* offset */ - eLazyBoolNo, /* skip_prologue */ - true, /* internal */ - false /* request_hardware */); + ModuleSP interpreter = LoadInterpreterModule(); + if (!interpreter) { + FileSpecList containingModules; + containingModules.Append( + m_process->GetTarget().GetExecutableModulePointer()->GetFileSpec()); + + dyld_break = target.CreateBreakpoint( + &containingModules, /*containingSourceFiles=*/nullptr, + DebugStateCandidates, eFunctionNameTypeFull, eLanguageTypeC, + /*offset=*/0, + /*skip_prologue=*/eLazyBoolNo, + /*internal=*/true, + /*request_hardware=*/false); + } else { + FileSpecList containingModules; + containingModules.Append(interpreter->GetFileSpec()); + dyld_break = target.CreateBreakpoint( + &containingModules, /*containingSourceFiles=*/nullptr, + DebugStateCandidates, eFunctionNameTypeFull, eLanguageTypeC, + /*offset=*/0, + /*skip_prologue=*/eLazyBoolNo, + /*internal=*/true, + /*request_hardware=*/false); + } } if (dyld_break->GetNumResolvedLocations() != 1) { @@ -442,14 +440,18 @@ void DynamicLoaderPOSIXDYLD::RefreshModules() { if (module_sp->GetObjectFile()->GetBaseAddress().GetLoadAddress( &m_process->GetTarget()) == m_interpreter_base && module_sp != m_interpreter_module.lock()) { - // If this is a duplicate instance of ld.so, unload it. We may end up - // with it if we load it via a different path than before (symlink - // vs real path). - // TODO: remove this once we either fix library matching or avoid - // loading the interpreter when setting the rendezvous breakpoint. - UnloadSections(module_sp); - loaded_modules.Remove(module_sp); - continue; + if (m_interpreter_module.lock() == nullptr) { + m_interpreter_module = module_sp; + } else { + // If this is a duplicate instance of ld.so, unload it. We may end + // up with it if we load it via a different path than before + // (symlink vs real path). + // TODO: remove this once we either fix library matching or avoid + // loading the interpreter when setting the rendezvous breakpoint. + UnloadSections(module_sp); + loaded_modules.Remove(module_sp); + continue; + } } loaded_modules.AppendIfNeeded(module_sp); @@ -620,6 +622,7 @@ void DynamicLoaderPOSIXDYLD::LoadAllCurrentModules() { } m_process->GetTarget().ModulesDidLoad(module_list); + m_initial_modules_added = true; } addr_t DynamicLoaderPOSIXDYLD::ComputeLoadOffset() { diff --git a/contrib/llvm-project/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.h b/contrib/llvm-project/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.h index 61567801fdd0..422856e7a660 100644 --- a/contrib/llvm-project/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.h +++ b/contrib/llvm-project/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.h @@ -30,9 +30,9 @@ public: static void Terminate(); - static lldb_private::ConstString GetPluginNameStatic(); + static llvm::StringRef GetPluginNameStatic() { return "posix-dyld"; } - static const char *GetPluginDescriptionStatic(); + static llvm::StringRef GetPluginDescriptionStatic(); static lldb_private::DynamicLoader * CreateInstance(lldb_private::Process *process, bool force); @@ -53,9 +53,7 @@ public: lldb::addr_t tls_file_addr) override; // PluginInterface protocol - lldb_private::ConstString GetPluginName() override; - - uint32_t GetPluginVersion() override; + llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); } protected: /// Runtime linker rendezvous structure. diff --git a/contrib/llvm-project/lldb/source/Plugins/DynamicLoader/Static/DynamicLoaderStatic.cpp b/contrib/llvm-project/lldb/source/Plugins/DynamicLoader/Static/DynamicLoaderStatic.cpp index 8a5528f1e474..a39aa2280ab8 100644 --- a/contrib/llvm-project/lldb/source/Plugins/DynamicLoader/Static/DynamicLoaderStatic.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/DynamicLoader/Static/DynamicLoaderStatic.cpp @@ -152,19 +152,7 @@ void DynamicLoaderStatic::Terminate() { PluginManager::UnregisterPlugin(CreateInstance); } -lldb_private::ConstString DynamicLoaderStatic::GetPluginNameStatic() { - static ConstString g_name("static"); - return g_name; -} - -const char *DynamicLoaderStatic::GetPluginDescriptionStatic() { +llvm::StringRef DynamicLoaderStatic::GetPluginDescriptionStatic() { return "Dynamic loader plug-in that will load any images at the static " "addresses contained in each image."; } - -// PluginInterface protocol -lldb_private::ConstString DynamicLoaderStatic::GetPluginName() { - return GetPluginNameStatic(); -} - -uint32_t DynamicLoaderStatic::GetPluginVersion() { return 1; } diff --git a/contrib/llvm-project/lldb/source/Plugins/DynamicLoader/Static/DynamicLoaderStatic.h b/contrib/llvm-project/lldb/source/Plugins/DynamicLoader/Static/DynamicLoaderStatic.h index 1a36c7851c2a..dac19dcd38d7 100644 --- a/contrib/llvm-project/lldb/source/Plugins/DynamicLoader/Static/DynamicLoaderStatic.h +++ b/contrib/llvm-project/lldb/source/Plugins/DynamicLoader/Static/DynamicLoaderStatic.h @@ -23,9 +23,9 @@ public: static void Terminate(); - static lldb_private::ConstString GetPluginNameStatic(); + static llvm::StringRef GetPluginNameStatic() { return "static"; } - static const char *GetPluginDescriptionStatic(); + static llvm::StringRef GetPluginDescriptionStatic(); static lldb_private::DynamicLoader * CreateInstance(lldb_private::Process *process, bool force); @@ -44,9 +44,7 @@ public: lldb_private::Status CanLoadImage() override; // PluginInterface protocol - lldb_private::ConstString GetPluginName() override; - - uint32_t GetPluginVersion() override; + llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); } private: void LoadAllImagesAtFileAddresses(); diff --git a/contrib/llvm-project/lldb/source/Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.cpp b/contrib/llvm-project/lldb/source/Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.cpp index 54dfa3e9d6f2..bf6dc57003d5 100644 --- a/contrib/llvm-project/lldb/source/Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.cpp @@ -37,12 +37,7 @@ void DynamicLoaderWindowsDYLD::Initialize() { void DynamicLoaderWindowsDYLD::Terminate() {} -ConstString DynamicLoaderWindowsDYLD::GetPluginNameStatic() { - static ConstString g_plugin_name("windows-dyld"); - return g_plugin_name; -} - -const char *DynamicLoaderWindowsDYLD::GetPluginDescriptionStatic() { +llvm::StringRef DynamicLoaderWindowsDYLD::GetPluginDescriptionStatic() { return "Dynamic loader plug-in that watches for shared library " "loads/unloads in Windows processes."; } @@ -174,12 +169,6 @@ void DynamicLoaderWindowsDYLD::DidLaunch() { Status DynamicLoaderWindowsDYLD::CanLoadImage() { return Status(); } -ConstString DynamicLoaderWindowsDYLD::GetPluginName() { - return GetPluginNameStatic(); -} - -uint32_t DynamicLoaderWindowsDYLD::GetPluginVersion() { return 1; } - ThreadPlanSP DynamicLoaderWindowsDYLD::GetStepThroughTrampolinePlan(Thread &thread, bool stop) { diff --git a/contrib/llvm-project/lldb/source/Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.h b/contrib/llvm-project/lldb/source/Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.h index 502a4c160ddd..42ea5aacecb4 100644 --- a/contrib/llvm-project/lldb/source/Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.h +++ b/contrib/llvm-project/lldb/source/Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.h @@ -24,8 +24,8 @@ public: static void Initialize(); static void Terminate(); - static ConstString GetPluginNameStatic(); - static const char *GetPluginDescriptionStatic(); + static llvm::StringRef GetPluginNameStatic() { return "windows-dyld"; } + static llvm::StringRef GetPluginDescriptionStatic(); static DynamicLoader *CreateInstance(Process *process, bool force); @@ -39,8 +39,7 @@ public: lldb::ThreadPlanSP GetStepThroughTrampolinePlan(Thread &thread, bool stop) override; - ConstString GetPluginName() override; - uint32_t GetPluginVersion() override; + llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); } protected: lldb::addr_t GetLoadAddress(lldb::ModuleSP executable); diff --git a/contrib/llvm-project/lldb/source/Plugins/DynamicLoader/wasm-DYLD/DynamicLoaderWasmDYLD.cpp b/contrib/llvm-project/lldb/source/Plugins/DynamicLoader/wasm-DYLD/DynamicLoaderWasmDYLD.cpp index ae7e011eaa52..1634372bb905 100644 --- a/contrib/llvm-project/lldb/source/Plugins/DynamicLoader/wasm-DYLD/DynamicLoaderWasmDYLD.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/DynamicLoader/wasm-DYLD/DynamicLoaderWasmDYLD.cpp @@ -30,12 +30,7 @@ void DynamicLoaderWasmDYLD::Initialize() { GetPluginDescriptionStatic(), CreateInstance); } -ConstString DynamicLoaderWasmDYLD::GetPluginNameStatic() { - static ConstString g_plugin_name("wasm-dyld"); - return g_plugin_name; -} - -const char *DynamicLoaderWasmDYLD::GetPluginDescriptionStatic() { +llvm::StringRef DynamicLoaderWasmDYLD::GetPluginDescriptionStatic() { return "Dynamic loader plug-in that watches for shared library " "loads/unloads in WebAssembly engines."; } diff --git a/contrib/llvm-project/lldb/source/Plugins/DynamicLoader/wasm-DYLD/DynamicLoaderWasmDYLD.h b/contrib/llvm-project/lldb/source/Plugins/DynamicLoader/wasm-DYLD/DynamicLoaderWasmDYLD.h index 4a18972bb848..fe67e5885904 100644 --- a/contrib/llvm-project/lldb/source/Plugins/DynamicLoader/wasm-DYLD/DynamicLoaderWasmDYLD.h +++ b/contrib/llvm-project/lldb/source/Plugins/DynamicLoader/wasm-DYLD/DynamicLoaderWasmDYLD.h @@ -21,8 +21,8 @@ public: static void Initialize(); static void Terminate() {} - static ConstString GetPluginNameStatic(); - static const char *GetPluginDescriptionStatic(); + static llvm::StringRef GetPluginNameStatic() { return "wasm-dyld"; } + static llvm::StringRef GetPluginDescriptionStatic(); static DynamicLoader *CreateInstance(Process *process, bool force); @@ -37,8 +37,7 @@ public: /// PluginInterface protocol. /// \{ - ConstString GetPluginName() override { return GetPluginNameStatic(); } - uint32_t GetPluginVersion() override { return 1; } + llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); } /// \} }; diff --git a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangASTImporter.cpp b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangASTImporter.cpp index 94647b0ef978..80469e292580 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangASTImporter.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangASTImporter.cpp @@ -824,7 +824,7 @@ ClangASTImporter::ASTImporterDelegate::ImportImpl(Decl *From) { } // Check which ASTContext this declaration originally came from. - DeclOrigin origin = m_master.GetDeclOrigin(From); + DeclOrigin origin = m_main.GetDeclOrigin(From); // Prevent infinite recursion when the origin tracking contains a cycle. assert(origin.decl != From && "Origin points to itself?"); @@ -853,7 +853,7 @@ ClangASTImporter::ASTImporterDelegate::ImportImpl(Decl *From) { // though all these different source ASTContexts just got a copy from // one source AST). if (origin.Valid()) { - auto R = m_master.CopyDecl(&getToContext(), origin.decl); + auto R = m_main.CopyDecl(&getToContext(), origin.decl); if (R) { RegisterImportedDecl(From, R); return R; @@ -862,7 +862,7 @@ ClangASTImporter::ASTImporterDelegate::ImportImpl(Decl *From) { // If we have a forcefully completed type, try to find an actual definition // for it in other modules. - const ClangASTMetadata *md = m_master.GetDeclMetadata(From); + const ClangASTMetadata *md = m_main.GetDeclMetadata(From); auto *td = dyn_cast<TagDecl>(From); if (td && md && md->IsForcefullyCompleted()) { Log *log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS); @@ -888,37 +888,6 @@ ClangASTImporter::ASTImporterDelegate::ImportImpl(Decl *From) { LLDB_LOG(log, "[ClangASTImporter] Complete definition not found"); } - // Disable the minimal import for fields that have record types. There is - // no point in minimally importing the record behind their type as Clang - // will anyway request their definition when the FieldDecl is added to the - // RecordDecl (as Clang will query the FieldDecl's type for things such - // as a deleted constexpr destructor). - // By importing the type ahead of time we avoid some corner cases where - // the FieldDecl's record is importing in the middle of Clang's - // `DeclContext::addDecl` logic. - if (clang::FieldDecl *fd = dyn_cast<FieldDecl>(From)) { - // This is only necessary because we do the 'minimal import'. Remove this - // once LLDB stopped using that mode. - assert(isMinimalImport() && "Only necessary for minimal import"); - QualType field_type = fd->getType(); - if (field_type->isRecordType()) { - // First get the underlying record and minimally import it. - clang::TagDecl *record_decl = field_type->getAsTagDecl(); - llvm::Expected<Decl *> imported = Import(record_decl); - if (!imported) - return imported.takeError(); - // Check how/if the import got redirected to a different AST. Now - // import the definition of what was actually imported. If there is no - // origin then that means the record was imported by just picking a - // compatible type in the target AST (in which case there is no more - // importing to do). - if (clang::Decl *origin = m_master.GetDeclOrigin(*imported).decl) { - if (llvm::Error def_err = ImportDefinition(record_decl)) - return std::move(def_err); - } - } - } - return ASTImporter::ImportImpl(From); } @@ -1076,7 +1045,7 @@ void ClangASTImporter::ASTImporterDelegate::Imported(clang::Decl *from, } lldb::user_id_t user_id = LLDB_INVALID_UID; - ClangASTMetadata *metadata = m_master.GetDeclMetadata(from); + ClangASTMetadata *metadata = m_main.GetDeclMetadata(from); if (metadata) user_id = metadata->GetUserID(); @@ -1100,9 +1069,9 @@ void ClangASTImporter::ASTImporterDelegate::Imported(clang::Decl *from, } ASTContextMetadataSP to_context_md = - m_master.GetContextMetadata(&to->getASTContext()); + m_main.GetContextMetadata(&to->getASTContext()); ASTContextMetadataSP from_context_md = - m_master.MaybeGetContextMetadata(m_source_ctx); + m_main.MaybeGetContextMetadata(m_source_ctx); if (from_context_md) { DeclOrigin origin = from_context_md->getOrigin(from); @@ -1113,7 +1082,7 @@ void ClangASTImporter::ASTImporterDelegate::Imported(clang::Decl *from, to_context_md->setOrigin(to, origin); ImporterDelegateSP direct_completer = - m_master.GetDelegate(&to->getASTContext(), origin.ctx); + m_main.GetDelegate(&to->getASTContext(), origin.ctx); if (direct_completer.get() != this) direct_completer->ASTImporter::Imported(origin.decl, to); @@ -1174,7 +1143,7 @@ void ClangASTImporter::ASTImporterDelegate::Imported(clang::Decl *from, } if (auto *to_namespace_decl = dyn_cast<NamespaceDecl>(to)) { - m_master.BuildNamespaceMap(to_namespace_decl); + m_main.BuildNamespaceMap(to_namespace_decl); to_namespace_decl->setHasExternalVisibleStorage(); } @@ -1203,10 +1172,10 @@ void ClangASTImporter::ASTImporterDelegate::Imported(clang::Decl *from, } if (clang::CXXMethodDecl *to_method = dyn_cast<CXXMethodDecl>(to)) - MaybeCompleteReturnType(m_master, to_method); + MaybeCompleteReturnType(m_main, to_method); } clang::Decl * ClangASTImporter::ASTImporterDelegate::GetOriginalDecl(clang::Decl *To) { - return m_master.GetDeclOrigin(To).decl; + return m_main.GetDeclOrigin(To).decl; } diff --git a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangASTImporter.h b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangASTImporter.h index 4f589d34aa48..e565a96b217f 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangASTImporter.h +++ b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangASTImporter.h @@ -259,11 +259,11 @@ public: /// CxxModuleHandler to replace any missing or malformed declarations with /// their counterpart from a C++ module. struct ASTImporterDelegate : public clang::ASTImporter { - ASTImporterDelegate(ClangASTImporter &master, clang::ASTContext *target_ctx, + ASTImporterDelegate(ClangASTImporter &main, clang::ASTContext *target_ctx, clang::ASTContext *source_ctx) - : clang::ASTImporter(*target_ctx, master.m_file_manager, *source_ctx, - master.m_file_manager, true /*minimal*/), - m_master(master), m_source_ctx(source_ctx) { + : clang::ASTImporter(*target_ctx, main.m_file_manager, *source_ctx, + main.m_file_manager, true /*minimal*/), + m_main(main), m_source_ctx(source_ctx) { // Target and source ASTContext shouldn't be identical. Importing AST // nodes within the same AST doesn't make any sense as the whole idea // is to import them to a different AST. @@ -329,7 +329,7 @@ public: /// were created from the 'std' C++ module to prevent that the Importer /// tries to sync them with the broken equivalent in the debug info AST. llvm::SmallPtrSet<clang::Decl *, 16> m_decls_to_ignore; - ClangASTImporter &m_master; + ClangASTImporter &m_main; clang::ASTContext *m_source_ctx; CxxModuleHandler *m_std_handler = nullptr; /// The currently attached listener. diff --git a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp index b43423707ae1..410d8a95cb12 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp @@ -479,7 +479,10 @@ void ClangASTSource::FindExternalLexicalDecls( decl->getDeclKindName(), ast_dump); } - CopyDecl(decl); + Decl *copied_decl = CopyDecl(decl); + + if (!copied_decl) + continue; // FIXME: We should add the copied decl to the 'decls' list. This would // add the copied Decl into the DeclContext and make sure that we @@ -489,6 +492,12 @@ void ClangASTSource::FindExternalLexicalDecls( // lookup issues later on. // We can't just add them for now as the ASTImporter already added the // decl into the DeclContext and this would add it twice. + + if (FieldDecl *copied_field = dyn_cast<FieldDecl>(copied_decl)) { + QualType copied_field_type = copied_field->getType(); + + m_ast_importer_sp->RequireCompleteType(copied_field_type); + } } else { SkippedDecls = true; } @@ -974,8 +983,9 @@ void ClangASTSource::FindObjCMethodDecls(NameSearchContext &context) { interface_decl->getName(), selector_name); SymbolContextList sc_list; - const bool include_symbols = false; - const bool include_inlines = false; + ModuleFunctionSearchOptions function_options; + function_options.include_symbols = false; + function_options.include_inlines = false; std::string interface_name = interface_decl->getNameAsString(); @@ -986,9 +996,9 @@ void ClangASTSource::FindObjCMethodDecls(NameSearchContext &context) { ConstString instance_method_name(ms.GetString()); sc_list.Clear(); - m_target->GetImages().FindFunctions( - instance_method_name, lldb::eFunctionNameTypeFull, include_symbols, - include_inlines, sc_list); + m_target->GetImages().FindFunctions(instance_method_name, + lldb::eFunctionNameTypeFull, + function_options, sc_list); if (sc_list.GetSize()) break; @@ -999,9 +1009,9 @@ void ClangASTSource::FindObjCMethodDecls(NameSearchContext &context) { ConstString class_method_name(ms.GetString()); sc_list.Clear(); - m_target->GetImages().FindFunctions( - class_method_name, lldb::eFunctionNameTypeFull, include_symbols, - include_inlines, sc_list); + m_target->GetImages().FindFunctions(class_method_name, + lldb::eFunctionNameTypeFull, + function_options, sc_list); if (sc_list.GetSize()) break; @@ -1012,9 +1022,9 @@ void ClangASTSource::FindObjCMethodDecls(NameSearchContext &context) { SymbolContextList candidate_sc_list; - m_target->GetImages().FindFunctions( - selector_name, lldb::eFunctionNameTypeSelector, include_symbols, - include_inlines, candidate_sc_list); + m_target->GetImages().FindFunctions(selector_name, + lldb::eFunctionNameTypeSelector, + function_options, candidate_sc_list); for (uint32_t ci = 0, ce = candidate_sc_list.GetSize(); ci != ce; ++ci) { SymbolContext candidate_sc; @@ -1494,7 +1504,7 @@ bool ClangASTSource::layoutRecordType(const RecordDecl *record, uint64_t &size, LLDB_LOG(log, "LayoutRecordType on (ASTContext*){0} '{1}' for (RecordDecl*)" - "{3} [name = '{4}']", + "{2} [name = '{3}']", m_ast_context, m_clang_ast_context->getDisplayName(), record, record->getName()); @@ -1570,8 +1580,10 @@ bool ClangASTSource::layoutRecordType(const RecordDecl *record, uint64_t &size, fe = record->field_end(); fi != fe; ++fi) { LLDB_LOG(log, - "LRT (FieldDecl*){0}, Name = '{1}', Offset = {2} bits", - *fi, fi->getName(), field_offsets[*fi]); + "LRT (FieldDecl*){0}, Name = '{1}', Type = '{2}', Offset = " + "{3} bits", + *fi, fi->getName(), fi->getType().getAsString(), + field_offsets[*fi]); } DeclFromParser<const CXXRecordDecl> parser_cxx_record = DynCast<const CXXRecordDecl>(parser_record); diff --git a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp index 731b81c61a6f..846c1597292b 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp @@ -59,9 +59,7 @@ using namespace lldb; using namespace lldb_private; using namespace clang; -namespace { -const char *g_lldb_local_vars_namespace_cstr = "$__lldb_local_vars"; -} // anonymous namespace +static const char *g_lldb_local_vars_namespace_cstr = "$__lldb_local_vars"; ClangExpressionDeclMap::ClangExpressionDeclMap( bool keep_result_in_memory, @@ -1220,22 +1218,25 @@ void ClangExpressionDeclMap::LookupFunction( } } - const bool include_inlines = false; SymbolContextList sc_list; if (namespace_decl && module_sp) { - const bool include_symbols = false; + ModuleFunctionSearchOptions function_options; + function_options.include_inlines = false; + function_options.include_symbols = false; module_sp->FindFunctions(name, namespace_decl, eFunctionNameTypeBase, - include_symbols, include_inlines, sc_list); + function_options, sc_list); } else if (target && !namespace_decl) { - const bool include_symbols = true; + ModuleFunctionSearchOptions function_options; + function_options.include_inlines = false; + function_options.include_symbols = true; // TODO Fix FindFunctions so that it doesn't return // instance methods for eFunctionNameTypeBase. target->GetImages().FindFunctions( - name, eFunctionNameTypeFull | eFunctionNameTypeBase, include_symbols, - include_inlines, sc_list); + name, eFunctionNameTypeFull | eFunctionNameTypeBase, function_options, + sc_list); } // If we found more than one function, see if we can use the frame's decl diff --git a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp index 0b5e1ab059d2..a0cff3cc9bf8 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp @@ -1069,7 +1069,7 @@ ClangExpressionParser::ParseInternal(DiagnosticManager &diagnostic_manager, } if (temp_fd != -1) { - lldb_private::NativeFile file(temp_fd, File::eOpenOptionWrite, true); + lldb_private::NativeFile file(temp_fd, File::eOpenOptionWriteOnly, true); const size_t expr_text_len = strlen(expr_text); size_t bytes_written = expr_text_len; if (file.Write(expr_text, bytes_written).Success()) { @@ -1309,7 +1309,7 @@ static bool FindFunctionInModule(ConstString &mangled_name, llvm::Module *module, const char *orig_name) { for (const auto &func : module->getFunctionList()) { const StringRef &name = func.getName(); - if (name.find(orig_name) != StringRef::npos) { + if (name.contains(orig_name)) { mangled_name.SetString(name); return true; } diff --git a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionSourceCode.cpp b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionSourceCode.cpp index 31707f81a270..977a461e3f6f 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionSourceCode.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionSourceCode.cpp @@ -311,8 +311,7 @@ bool ClangExpressionSourceCode::GetText( } if (target->GetArchitecture().GetMachine() == llvm::Triple::x86_64) { if (lldb::PlatformSP platform_sp = target->GetPlatform()) { - static ConstString g_platform_ios_simulator("ios-simulator"); - if (platform_sp->GetPluginName() == g_platform_ios_simulator) { + if (platform_sp->GetPluginName() == "ios-simulator") { target_specific_defines = "typedef bool BOOL;\n"; } } diff --git a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp index 1b205b13113b..50e9f7827838 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp @@ -6,12 +6,8 @@ // //===----------------------------------------------------------------------===// -#include "lldb/Host/Config.h" - #include <cstdio> -#if HAVE_SYS_TYPES_H #include <sys/types.h> -#endif #include <cstdlib> #include <map> @@ -689,15 +685,22 @@ bool ClangUserExpression::Parse(DiagnosticManager &diagnostic_manager, SetupCppModuleImports(exe_ctx); // If we did load any modules, then retry parsing. if (!m_imported_cpp_modules.empty()) { + // Create a dedicated diagnostic manager for the second parse attempt. + // These diagnostics are only returned to the caller if using the fallback + // actually succeeded in getting the expression to parse. This prevents + // that module-specific issues regress diagnostic quality with the + // fallback mode. + DiagnosticManager retry_manager; // The module imports are injected into the source code wrapper, // so recreate those. - CreateSourceCode(diagnostic_manager, exe_ctx, m_imported_cpp_modules, + CreateSourceCode(retry_manager, exe_ctx, m_imported_cpp_modules, /*for_completion*/ false); - // Clear the error diagnostics from the previous parse attempt. - diagnostic_manager.Clear(); - parse_success = TryParse(diagnostic_manager, exe_scope, exe_ctx, + parse_success = TryParse(retry_manager, exe_scope, exe_ctx, execution_policy, keep_result_in_memory, generate_debug_info); + // Return the parse diagnostics if we were successful. + if (parse_success) + diagnostic_manager = std::move(retry_manager); } } if (!parse_success) @@ -907,8 +910,8 @@ bool ClangUserExpression::AddArguments(ExecutionContext &exe_ctx, if (!object_ptr_error.Success()) { exe_ctx.GetTargetRef().GetDebugger().GetAsyncOutputStream()->Printf( - "warning: `%s' is not accessible (substituting 0)\n", - object_name.AsCString()); + "warning: `%s' is not accessible (substituting 0). %s\n", + object_name.AsCString(), object_ptr_error.AsCString()); object_ptr = 0; } diff --git a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.cpp b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.cpp index a78116352c2e..3db3fcea0192 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.cpp @@ -6,8 +6,6 @@ // //===----------------------------------------------------------------------===// -#include "lldb/Host/Config.h" - #include "ClangUtilityFunction.h" #include "ClangExpressionDeclMap.h" #include "ClangExpressionParser.h" @@ -15,9 +13,7 @@ #include "ClangPersistentVariables.h" #include <cstdio> -#if HAVE_SYS_TYPES_H #include <sys/types.h> -#endif #include "lldb/Core/Module.h" @@ -49,7 +45,7 @@ ClangUtilityFunction::ClangUtilityFunction(ExecutionContextScope &exe_scope, llvm::SmallString<128> result_path; llvm::sys::fs::createTemporaryFile("lldb", "expr", temp_fd, result_path); if (temp_fd != -1) { - lldb_private::NativeFile file(temp_fd, File::eOpenOptionWrite, true); + lldb_private::NativeFile file(temp_fd, File::eOpenOptionWriteOnly, true); text = "#line 1 \"" + std::string(result_path) + "\"\n" + text; size_t bytes_written = text.size(); file.Write(text.c_str(), bytes_written); diff --git a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/CppModuleConfiguration.h b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/CppModuleConfiguration.h index 425106bba0a3..907db5d625dc 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/CppModuleConfiguration.h +++ b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/CppModuleConfiguration.h @@ -16,9 +16,9 @@ namespace lldb_private { /// A Clang configuration when importing C++ modules. /// -/// Includes a list of include paths that should be used when importing -/// and a list of modules that can be imported. Currently only used when -/// importing the 'std' module and its dependencies. +/// This class computes a list of include paths and module names that can be +/// imported given a list of source files. Currently only used when importing +/// the 'std' module and its dependencies. class CppModuleConfiguration { /// Utility class for a path that can only be set once. class SetOncePath { diff --git a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/IRForTarget.cpp b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/IRForTarget.cpp index 5655d548ee34..f80dc2b14467 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/IRForTarget.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/IRForTarget.cpp @@ -1303,7 +1303,7 @@ bool IRForTarget::MaybeHandleCallArguments(CallInst *Old) { LLDB_LOG(log, "MaybeHandleCallArguments({0})", PrintValue(Old)); - for (unsigned op_index = 0, num_ops = Old->getNumArgOperands(); + for (unsigned op_index = 0, num_ops = Old->arg_size(); op_index < num_ops; ++op_index) // conservatively believe that this is a store if (!MaybeHandleVariable(Old->getArgOperand(op_index))) { diff --git a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/NameSearchContext.cpp b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/NameSearchContext.cpp index 829afa5ffcec..8709c2b0dcea 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/NameSearchContext.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/NameSearchContext.cpp @@ -66,6 +66,7 @@ clang::NamedDecl *NameSearchContext::AddFunDecl(const CompilerType &type, context = LinkageSpecDecl::Create( ast, context, SourceLocation(), SourceLocation(), clang::LinkageSpecDecl::LanguageIDs::lang_c, false); + // FIXME: The LinkageSpecDecl here should be added to m_decl_context. } // Pass the identifier info for functions the decl_name is needed for @@ -77,7 +78,7 @@ clang::NamedDecl *NameSearchContext::AddFunDecl(const CompilerType &type, clang::FunctionDecl *func_decl = FunctionDecl::Create( ast, context, SourceLocation(), SourceLocation(), decl_name, qual_type, - nullptr, SC_Extern, isInlineSpecified, hasWrittenPrototype, + nullptr, SC_Extern, /*UsesFPIntrin=*/false, isInlineSpecified, hasWrittenPrototype, isConstexprSpecified ? ConstexprSpecKind::Constexpr : ConstexprSpecKind::Unspecified); diff --git a/contrib/llvm-project/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp b/contrib/llvm-project/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp index bf0bbdab740f..5a238c5d4ac7 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp @@ -713,12 +713,7 @@ void EmulateInstructionARM::Terminate() { PluginManager::UnregisterPlugin(CreateInstance); } -ConstString EmulateInstructionARM::GetPluginNameStatic() { - static ConstString g_name("arm"); - return g_name; -} - -const char *EmulateInstructionARM::GetPluginDescriptionStatic() { +llvm::StringRef EmulateInstructionARM::GetPluginDescriptionStatic() { return "Emulate instructions for the ARM architecture."; } diff --git a/contrib/llvm-project/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.h b/contrib/llvm-project/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.h index dfd7c926dabf..8b167dd347ad 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.h +++ b/contrib/llvm-project/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.h @@ -62,9 +62,9 @@ public: static void Terminate(); - static lldb_private::ConstString GetPluginNameStatic(); + static llvm::StringRef GetPluginNameStatic() { return "arm"; } - static const char *GetPluginDescriptionStatic(); + static llvm::StringRef GetPluginDescriptionStatic(); static lldb_private::EmulateInstruction * CreateInstance(const lldb_private::ArchSpec &arch, InstructionType inst_type); @@ -83,11 +83,7 @@ public: return false; } - lldb_private::ConstString GetPluginName() override { - return GetPluginNameStatic(); - } - - uint32_t GetPluginVersion() override { return 1; } + llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); } bool SetTargetTriple(const ArchSpec &arch) override; diff --git a/contrib/llvm-project/lldb/source/Plugins/Instruction/ARM64/EmulateInstructionARM64.cpp b/contrib/llvm-project/lldb/source/Plugins/Instruction/ARM64/EmulateInstructionARM64.cpp index 9b0c06bcccab..f86609f3c5c1 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Instruction/ARM64/EmulateInstructionARM64.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Instruction/ARM64/EmulateInstructionARM64.cpp @@ -35,7 +35,7 @@ "na", nullptr, 8, 0, lldb::eEncodingUint, lldb::eFormatHex, \ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, \ - nullptr, nullptr, nullptr, 0 + nullptr, nullptr #define DECLARE_REGISTER_INFOS_ARM64_STRUCT @@ -117,17 +117,7 @@ void EmulateInstructionARM64::Terminate() { PluginManager::UnregisterPlugin(CreateInstance); } -ConstString EmulateInstructionARM64::GetPluginNameStatic() { - ConstString g_plugin_name("lldb.emulate-instruction.arm64"); - return g_plugin_name; -} - -lldb_private::ConstString EmulateInstructionARM64::GetPluginName() { - static ConstString g_plugin_name("EmulateInstructionARM64"); - return g_plugin_name; -} - -const char *EmulateInstructionARM64::GetPluginDescriptionStatic() { +llvm::StringRef EmulateInstructionARM64::GetPluginDescriptionStatic() { return "Emulate instructions for the ARM64 architecture."; } diff --git a/contrib/llvm-project/lldb/source/Plugins/Instruction/ARM64/EmulateInstructionARM64.h b/contrib/llvm-project/lldb/source/Plugins/Instruction/ARM64/EmulateInstructionARM64.h index 11ad8a99b0fc..4f11f7387a2e 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Instruction/ARM64/EmulateInstructionARM64.h +++ b/contrib/llvm-project/lldb/source/Plugins/Instruction/ARM64/EmulateInstructionARM64.h @@ -24,9 +24,9 @@ public: static void Terminate(); - static lldb_private::ConstString GetPluginNameStatic(); + static llvm::StringRef GetPluginNameStatic() { return "arm64"; } - static const char *GetPluginDescriptionStatic(); + static llvm::StringRef GetPluginDescriptionStatic(); static lldb_private::EmulateInstruction * CreateInstance(const lldb_private::ArchSpec &arch, @@ -46,9 +46,7 @@ public: return false; } - lldb_private::ConstString GetPluginName() override; - - uint32_t GetPluginVersion() override { return 1; } + llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); } bool SetTargetTriple(const lldb_private::ArchSpec &arch) override; diff --git a/contrib/llvm-project/lldb/source/Plugins/Instruction/MIPS/EmulateInstructionMIPS.cpp b/contrib/llvm-project/lldb/source/Plugins/Instruction/MIPS/EmulateInstructionMIPS.cpp index a1a93c0b5a5f..ea9c95c55cbb 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Instruction/MIPS/EmulateInstructionMIPS.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Instruction/MIPS/EmulateInstructionMIPS.cpp @@ -29,7 +29,7 @@ #include "llvm/MC/MCRegisterInfo.h" #include "llvm/MC/MCSubtargetInfo.h" #include "llvm/MC/MCTargetOptions.h" -#include "llvm/Support/TargetRegistry.h" +#include "llvm/MC/TargetRegistry.h" #include "llvm/Support/TargetSelect.h" #include "llvm/ADT/STLExtras.h" @@ -193,17 +193,7 @@ void EmulateInstructionMIPS::Terminate() { PluginManager::UnregisterPlugin(CreateInstance); } -ConstString EmulateInstructionMIPS::GetPluginNameStatic() { - ConstString g_plugin_name("lldb.emulate-instruction.mips32"); - return g_plugin_name; -} - -lldb_private::ConstString EmulateInstructionMIPS::GetPluginName() { - static ConstString g_plugin_name("EmulateInstructionMIPS"); - return g_plugin_name; -} - -const char *EmulateInstructionMIPS::GetPluginDescriptionStatic() { +llvm::StringRef EmulateInstructionMIPS::GetPluginDescriptionStatic() { return "Emulate instructions for the MIPS32 architecture."; } @@ -2946,9 +2936,9 @@ bool EmulateInstructionMIPS::Emulate_MSA_Branch_V(llvm::MCInst &insn, bool bnz) { bool success = false; int32_t target = 0; - llvm::APInt wr_val = llvm::APInt::getNullValue(128); + llvm::APInt wr_val = llvm::APInt::getZero(128); llvm::APInt fail_value = llvm::APInt::getMaxValue(128); - llvm::APInt zero_value = llvm::APInt::getNullValue(128); + llvm::APInt zero_value = llvm::APInt::getZero(128); RegisterValue reg_value; uint32_t wt = m_reg_info->getEncodingValue(insn.getOperand(0).getReg()); diff --git a/contrib/llvm-project/lldb/source/Plugins/Instruction/MIPS/EmulateInstructionMIPS.h b/contrib/llvm-project/lldb/source/Plugins/Instruction/MIPS/EmulateInstructionMIPS.h index 61291c729879..48782186e065 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Instruction/MIPS/EmulateInstructionMIPS.h +++ b/contrib/llvm-project/lldb/source/Plugins/Instruction/MIPS/EmulateInstructionMIPS.h @@ -33,9 +33,9 @@ public: static void Terminate(); - static lldb_private::ConstString GetPluginNameStatic(); + static llvm::StringRef GetPluginNameStatic() { return "mips32"; } - static const char *GetPluginDescriptionStatic(); + static llvm::StringRef GetPluginDescriptionStatic(); static lldb_private::EmulateInstruction * CreateInstance(const lldb_private::ArchSpec &arch, @@ -55,9 +55,7 @@ public: return false; } - lldb_private::ConstString GetPluginName() override; - - uint32_t GetPluginVersion() override { return 1; } + llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); } bool SetTargetTriple(const lldb_private::ArchSpec &arch) override; diff --git a/contrib/llvm-project/lldb/source/Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.cpp b/contrib/llvm-project/lldb/source/Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.cpp index 6044d00c0cbf..e5732a50f3f2 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.cpp @@ -29,7 +29,7 @@ #include "llvm/MC/MCRegisterInfo.h" #include "llvm/MC/MCSubtargetInfo.h" #include "llvm/MC/MCTargetOptions.h" -#include "llvm/Support/TargetRegistry.h" +#include "llvm/MC/TargetRegistry.h" #include "llvm/Support/TargetSelect.h" #include "llvm/ADT/STLExtras.h" @@ -180,17 +180,7 @@ void EmulateInstructionMIPS64::Terminate() { PluginManager::UnregisterPlugin(CreateInstance); } -ConstString EmulateInstructionMIPS64::GetPluginNameStatic() { - ConstString g_plugin_name("lldb.emulate-instruction.mips64"); - return g_plugin_name; -} - -lldb_private::ConstString EmulateInstructionMIPS64::GetPluginName() { - static ConstString g_plugin_name("EmulateInstructionMIPS64"); - return g_plugin_name; -} - -const char *EmulateInstructionMIPS64::GetPluginDescriptionStatic() { +llvm::StringRef EmulateInstructionMIPS64::GetPluginDescriptionStatic() { return "Emulate instructions for the MIPS64 architecture."; } @@ -2258,9 +2248,9 @@ bool EmulateInstructionMIPS64::Emulate_MSA_Branch_V(llvm::MCInst &insn, bool bnz) { bool success = false; int64_t target = 0; - llvm::APInt wr_val = llvm::APInt::getNullValue(128); + llvm::APInt wr_val = llvm::APInt::getZero(128); llvm::APInt fail_value = llvm::APInt::getMaxValue(128); - llvm::APInt zero_value = llvm::APInt::getNullValue(128); + llvm::APInt zero_value = llvm::APInt::getZero(128); RegisterValue reg_value; uint32_t wt = m_reg_info->getEncodingValue(insn.getOperand(0).getReg()); diff --git a/contrib/llvm-project/lldb/source/Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.h b/contrib/llvm-project/lldb/source/Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.h index c4ae2296c5dd..acd956e613d4 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.h +++ b/contrib/llvm-project/lldb/source/Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.h @@ -31,9 +31,9 @@ public: static void Terminate(); - static lldb_private::ConstString GetPluginNameStatic(); + static llvm::StringRef GetPluginNameStatic() { return "mips64"; } - static const char *GetPluginDescriptionStatic(); + static llvm::StringRef GetPluginDescriptionStatic(); static lldb_private::EmulateInstruction * CreateInstance(const lldb_private::ArchSpec &arch, @@ -53,9 +53,7 @@ public: return false; } - lldb_private::ConstString GetPluginName() override; - - uint32_t GetPluginVersion() override { return 1; } + llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); } bool SetTargetTriple(const lldb_private::ArchSpec &arch) override; diff --git a/contrib/llvm-project/lldb/source/Plugins/Instruction/PPC64/EmulateInstructionPPC64.cpp b/contrib/llvm-project/lldb/source/Plugins/Instruction/PPC64/EmulateInstructionPPC64.cpp index 4e78c369c128..dcfad8e106aa 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Instruction/PPC64/EmulateInstructionPPC64.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Instruction/PPC64/EmulateInstructionPPC64.cpp @@ -39,17 +39,7 @@ void EmulateInstructionPPC64::Terminate() { PluginManager::UnregisterPlugin(CreateInstance); } -ConstString EmulateInstructionPPC64::GetPluginNameStatic() { - ConstString g_plugin_name("lldb.emulate-instruction.ppc64"); - return g_plugin_name; -} - -ConstString EmulateInstructionPPC64::GetPluginName() { - static ConstString g_plugin_name("EmulateInstructionPPC64"); - return g_plugin_name; -} - -const char *EmulateInstructionPPC64::GetPluginDescriptionStatic() { +llvm::StringRef EmulateInstructionPPC64::GetPluginDescriptionStatic() { return "Emulate instructions for the PPC64 architecture."; } diff --git a/contrib/llvm-project/lldb/source/Plugins/Instruction/PPC64/EmulateInstructionPPC64.h b/contrib/llvm-project/lldb/source/Plugins/Instruction/PPC64/EmulateInstructionPPC64.h index 02d2bce8f05e..117ff8965eb5 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Instruction/PPC64/EmulateInstructionPPC64.h +++ b/contrib/llvm-project/lldb/source/Plugins/Instruction/PPC64/EmulateInstructionPPC64.h @@ -23,9 +23,9 @@ public: static void Terminate(); - static ConstString GetPluginNameStatic(); + static llvm::StringRef GetPluginNameStatic() { return "ppc64"; } - static const char *GetPluginDescriptionStatic(); + static llvm::StringRef GetPluginDescriptionStatic(); static EmulateInstruction *CreateInstance(const ArchSpec &arch, InstructionType inst_type); @@ -44,9 +44,7 @@ public: return false; } - ConstString GetPluginName() override; - - uint32_t GetPluginVersion() override { return 1; } + llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); } bool SetTargetTriple(const ArchSpec &arch) override; diff --git a/contrib/llvm-project/lldb/source/Plugins/InstrumentationRuntime/ASan/InstrumentationRuntimeASan.cpp b/contrib/llvm-project/lldb/source/Plugins/InstrumentationRuntime/ASan/InstrumentationRuntimeASan.cpp index e78ea3a68483..8d8b5c68e41b 100644 --- a/contrib/llvm-project/lldb/source/Plugins/InstrumentationRuntime/ASan/InstrumentationRuntimeASan.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/InstrumentationRuntime/ASan/InstrumentationRuntimeASan.cpp @@ -47,10 +47,6 @@ void InstrumentationRuntimeASan::Terminate() { PluginManager::UnregisterPlugin(CreateInstance); } -lldb_private::ConstString InstrumentationRuntimeASan::GetPluginNameStatic() { - return ConstString("AddressSanitizer"); -} - lldb::InstrumentationRuntimeType InstrumentationRuntimeASan::GetTypeStatic() { return eInstrumentationRuntimeTypeAddressSanitizer; } diff --git a/contrib/llvm-project/lldb/source/Plugins/InstrumentationRuntime/ASan/InstrumentationRuntimeASan.h b/contrib/llvm-project/lldb/source/Plugins/InstrumentationRuntime/ASan/InstrumentationRuntimeASan.h index cde0a9613350..83a88cf7f89f 100644 --- a/contrib/llvm-project/lldb/source/Plugins/InstrumentationRuntime/ASan/InstrumentationRuntimeASan.h +++ b/contrib/llvm-project/lldb/source/Plugins/InstrumentationRuntime/ASan/InstrumentationRuntimeASan.h @@ -27,18 +27,14 @@ public: static void Terminate(); - static lldb_private::ConstString GetPluginNameStatic(); + static llvm::StringRef GetPluginNameStatic() { return "AddressSanitizer"; } static lldb::InstrumentationRuntimeType GetTypeStatic(); - lldb_private::ConstString GetPluginName() override { - return GetPluginNameStatic(); - } + llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); } virtual lldb::InstrumentationRuntimeType GetType() { return GetTypeStatic(); } - uint32_t GetPluginVersion() override { return 1; } - private: InstrumentationRuntimeASan(const lldb::ProcessSP &process_sp) : lldb_private::InstrumentationRuntime(process_sp) {} diff --git a/contrib/llvm-project/lldb/source/Plugins/InstrumentationRuntime/MainThreadChecker/InstrumentationRuntimeMainThreadChecker.cpp b/contrib/llvm-project/lldb/source/Plugins/InstrumentationRuntime/MainThreadChecker/InstrumentationRuntimeMainThreadChecker.cpp index 9a88b343878c..dc8c7c96aa11 100644 --- a/contrib/llvm-project/lldb/source/Plugins/InstrumentationRuntime/MainThreadChecker/InstrumentationRuntimeMainThreadChecker.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/InstrumentationRuntime/MainThreadChecker/InstrumentationRuntimeMainThreadChecker.cpp @@ -54,11 +54,6 @@ void InstrumentationRuntimeMainThreadChecker::Terminate() { PluginManager::UnregisterPlugin(CreateInstance); } -lldb_private::ConstString -InstrumentationRuntimeMainThreadChecker::GetPluginNameStatic() { - return ConstString("MainThreadChecker"); -} - lldb::InstrumentationRuntimeType InstrumentationRuntimeMainThreadChecker::GetTypeStatic() { return eInstrumentationRuntimeTypeMainThreadChecker; diff --git a/contrib/llvm-project/lldb/source/Plugins/InstrumentationRuntime/MainThreadChecker/InstrumentationRuntimeMainThreadChecker.h b/contrib/llvm-project/lldb/source/Plugins/InstrumentationRuntime/MainThreadChecker/InstrumentationRuntimeMainThreadChecker.h index 1435ae8d367f..3bbbf13b7798 100644 --- a/contrib/llvm-project/lldb/source/Plugins/InstrumentationRuntime/MainThreadChecker/InstrumentationRuntimeMainThreadChecker.h +++ b/contrib/llvm-project/lldb/source/Plugins/InstrumentationRuntime/MainThreadChecker/InstrumentationRuntimeMainThreadChecker.h @@ -28,18 +28,14 @@ public: static void Terminate(); - static lldb_private::ConstString GetPluginNameStatic(); + static llvm::StringRef GetPluginNameStatic() { return "MainThreadChecker"; } static lldb::InstrumentationRuntimeType GetTypeStatic(); - lldb_private::ConstString GetPluginName() override { - return GetPluginNameStatic(); - } + llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); } virtual lldb::InstrumentationRuntimeType GetType() { return GetTypeStatic(); } - uint32_t GetPluginVersion() override { return 1; } - lldb::ThreadCollectionSP GetBacktracesFromExtendedStopInfo(StructuredData::ObjectSP info) override; diff --git a/contrib/llvm-project/lldb/source/Plugins/InstrumentationRuntime/TSan/InstrumentationRuntimeTSan.cpp b/contrib/llvm-project/lldb/source/Plugins/InstrumentationRuntime/TSan/InstrumentationRuntimeTSan.cpp index a2954f556b10..aef10bb2a778 100644 --- a/contrib/llvm-project/lldb/source/Plugins/InstrumentationRuntime/TSan/InstrumentationRuntimeTSan.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/InstrumentationRuntime/TSan/InstrumentationRuntimeTSan.cpp @@ -52,10 +52,6 @@ void InstrumentationRuntimeTSan::Terminate() { PluginManager::UnregisterPlugin(CreateInstance); } -lldb_private::ConstString InstrumentationRuntimeTSan::GetPluginNameStatic() { - return ConstString("ThreadSanitizer"); -} - lldb::InstrumentationRuntimeType InstrumentationRuntimeTSan::GetTypeStatic() { return eInstrumentationRuntimeTypeThreadSanitizer; } diff --git a/contrib/llvm-project/lldb/source/Plugins/InstrumentationRuntime/TSan/InstrumentationRuntimeTSan.h b/contrib/llvm-project/lldb/source/Plugins/InstrumentationRuntime/TSan/InstrumentationRuntimeTSan.h index 35a878d90aff..db4466a13193 100644 --- a/contrib/llvm-project/lldb/source/Plugins/InstrumentationRuntime/TSan/InstrumentationRuntimeTSan.h +++ b/contrib/llvm-project/lldb/source/Plugins/InstrumentationRuntime/TSan/InstrumentationRuntimeTSan.h @@ -27,18 +27,14 @@ public: static void Terminate(); - static lldb_private::ConstString GetPluginNameStatic(); + static llvm::StringRef GetPluginNameStatic() { return "ThreadSanitizer"; } static lldb::InstrumentationRuntimeType GetTypeStatic(); - lldb_private::ConstString GetPluginName() override { - return GetPluginNameStatic(); - } + llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); } virtual lldb::InstrumentationRuntimeType GetType() { return GetTypeStatic(); } - uint32_t GetPluginVersion() override { return 1; } - lldb::ThreadCollectionSP GetBacktracesFromExtendedStopInfo(StructuredData::ObjectSP info) override; diff --git a/contrib/llvm-project/lldb/source/Plugins/InstrumentationRuntime/UBSan/InstrumentationRuntimeUBSan.cpp b/contrib/llvm-project/lldb/source/Plugins/InstrumentationRuntime/UBSan/InstrumentationRuntimeUBSan.cpp index 58bc38a551f0..8e7799dc0761 100644 --- a/contrib/llvm-project/lldb/source/Plugins/InstrumentationRuntime/UBSan/InstrumentationRuntimeUBSan.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/InstrumentationRuntime/UBSan/InstrumentationRuntimeUBSan.cpp @@ -56,10 +56,6 @@ void InstrumentationRuntimeUBSan::Terminate() { PluginManager::UnregisterPlugin(CreateInstance); } -lldb_private::ConstString InstrumentationRuntimeUBSan::GetPluginNameStatic() { - return ConstString("UndefinedBehaviorSanitizer"); -} - lldb::InstrumentationRuntimeType InstrumentationRuntimeUBSan::GetTypeStatic() { return eInstrumentationRuntimeTypeUndefinedBehaviorSanitizer; } diff --git a/contrib/llvm-project/lldb/source/Plugins/InstrumentationRuntime/UBSan/InstrumentationRuntimeUBSan.h b/contrib/llvm-project/lldb/source/Plugins/InstrumentationRuntime/UBSan/InstrumentationRuntimeUBSan.h index 813c30069600..e0de158473de 100644 --- a/contrib/llvm-project/lldb/source/Plugins/InstrumentationRuntime/UBSan/InstrumentationRuntimeUBSan.h +++ b/contrib/llvm-project/lldb/source/Plugins/InstrumentationRuntime/UBSan/InstrumentationRuntimeUBSan.h @@ -28,18 +28,16 @@ public: static void Terminate(); - static lldb_private::ConstString GetPluginNameStatic(); + static llvm::StringRef GetPluginNameStatic() { + return "UndefinedBehaviorSanitizer"; + } static lldb::InstrumentationRuntimeType GetTypeStatic(); - lldb_private::ConstString GetPluginName() override { - return GetPluginNameStatic(); - } + llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); } virtual lldb::InstrumentationRuntimeType GetType() { return GetTypeStatic(); } - uint32_t GetPluginVersion() override { return 1; } - lldb::ThreadCollectionSP GetBacktracesFromExtendedStopInfo(StructuredData::ObjectSP info) override; diff --git a/contrib/llvm-project/lldb/source/Plugins/JITLoader/GDB/JITLoaderGDB.cpp b/contrib/llvm-project/lldb/source/Plugins/JITLoader/GDB/JITLoaderGDB.cpp index 33dfc7b3281e..ff5c82752b37 100644 --- a/contrib/llvm-project/lldb/source/Plugins/JITLoader/GDB/JITLoaderGDB.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/JITLoader/GDB/JITLoaderGDB.cpp @@ -92,7 +92,7 @@ enum { class PluginProperties : public Properties { public: static ConstString GetSettingName() { - return JITLoaderGDB::GetPluginNameStatic(); + return ConstString(JITLoaderGDB::GetPluginNameStatic()); } PluginProperties() { @@ -107,11 +107,9 @@ public: } }; -typedef std::shared_ptr<PluginProperties> JITLoaderGDBPropertiesSP; - -static const JITLoaderGDBPropertiesSP &GetGlobalPluginProperties() { - static const auto g_settings_sp(std::make_shared<PluginProperties>()); - return g_settings_sp; +static PluginProperties &GetGlobalPluginProperties() { + static PluginProperties g_settings; + return g_settings; } template <typename ptr_t> @@ -162,7 +160,7 @@ void JITLoaderGDB::DebuggerInitialize(Debugger &debugger) { debugger, PluginProperties::GetSettingName())) { const bool is_global_setting = true; PluginManager::CreateSettingForJITLoaderPlugin( - debugger, GetGlobalPluginProperties()->GetValueProperties(), + debugger, GetGlobalPluginProperties().GetValueProperties(), ConstString("Properties for the JIT LoaderGDB plug-in."), is_global_setting); } @@ -409,15 +407,10 @@ bool JITLoaderGDB::ReadJITDescriptorImpl(bool all_entries) { } // PluginInterface protocol -lldb_private::ConstString JITLoaderGDB::GetPluginNameStatic() { - static ConstString g_name("gdb"); - return g_name; -} - JITLoaderSP JITLoaderGDB::CreateInstance(Process *process, bool force) { JITLoaderSP jit_loader_sp; bool enable; - switch (GetGlobalPluginProperties()->GetEnable()) { + switch (GetGlobalPluginProperties().GetEnable()) { case EnableJITLoaderGDB::eEnableJITLoaderGDBOn: enable = true; break; @@ -434,17 +427,11 @@ JITLoaderSP JITLoaderGDB::CreateInstance(Process *process, bool force) { return jit_loader_sp; } -const char *JITLoaderGDB::GetPluginDescriptionStatic() { +llvm::StringRef JITLoaderGDB::GetPluginDescriptionStatic() { return "JIT loader plug-in that watches for JIT events using the GDB " "interface."; } -lldb_private::ConstString JITLoaderGDB::GetPluginName() { - return GetPluginNameStatic(); -} - -uint32_t JITLoaderGDB::GetPluginVersion() { return 1; } - void JITLoaderGDB::Initialize() { PluginManager::RegisterPlugin(GetPluginNameStatic(), GetPluginDescriptionStatic(), CreateInstance, diff --git a/contrib/llvm-project/lldb/source/Plugins/JITLoader/GDB/JITLoaderGDB.h b/contrib/llvm-project/lldb/source/Plugins/JITLoader/GDB/JITLoaderGDB.h index 42377f435293..2b337b3e9844 100644 --- a/contrib/llvm-project/lldb/source/Plugins/JITLoader/GDB/JITLoaderGDB.h +++ b/contrib/llvm-project/lldb/source/Plugins/JITLoader/GDB/JITLoaderGDB.h @@ -25,9 +25,9 @@ public: static void Terminate(); - static lldb_private::ConstString GetPluginNameStatic(); + static llvm::StringRef GetPluginNameStatic() { return "gdb"; } - static const char *GetPluginDescriptionStatic(); + static llvm::StringRef GetPluginDescriptionStatic(); static lldb::JITLoaderSP CreateInstance(lldb_private::Process *process, bool force); @@ -35,9 +35,7 @@ public: static void DebuggerInitialize(lldb_private::Debugger &debugger); // PluginInterface protocol - lldb_private::ConstString GetPluginName() override; - - uint32_t GetPluginVersion() override; + llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); } // JITLoader interface void DidAttach() override; diff --git a/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp b/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp index 895fd55f499c..83e8e52b86f2 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp @@ -20,12 +20,14 @@ #include "llvm/Demangle/ItaniumDemangle.h" #include "lldb/Core/Mangled.h" +#include "lldb/Core/Module.h" #include "lldb/Core/PluginManager.h" #include "lldb/Core/UniqueCStringMap.h" #include "lldb/DataFormatters/CXXFunctionPointer.h" #include "lldb/DataFormatters/DataVisualization.h" #include "lldb/DataFormatters/FormattersHelpers.h" #include "lldb/DataFormatters/VectorType.h" +#include "lldb/Symbol/SymbolFile.h" #include "lldb/Utility/ConstString.h" #include "lldb/Utility/Log.h" #include "lldb/Utility/RegularExpression.h" @@ -54,24 +56,40 @@ void CPlusPlusLanguage::Terminate() { PluginManager::UnregisterPlugin(CreateInstance); } -lldb_private::ConstString CPlusPlusLanguage::GetPluginNameStatic() { - static ConstString g_name("cplusplus"); - return g_name; -} - bool CPlusPlusLanguage::SymbolNameFitsToLanguage(Mangled mangled) const { const char *mangled_name = mangled.GetMangledName().GetCString(); return mangled_name && CPlusPlusLanguage::IsCPPMangledName(mangled_name); } -// PluginInterface protocol - -lldb_private::ConstString CPlusPlusLanguage::GetPluginName() { - return GetPluginNameStatic(); +ConstString CPlusPlusLanguage::GetDemangledFunctionNameWithoutArguments( + Mangled mangled) const { + const char *mangled_name_cstr = mangled.GetMangledName().GetCString(); + ConstString demangled_name = mangled.GetDemangledName(); + if (demangled_name && mangled_name_cstr && mangled_name_cstr[0]) { + if (mangled_name_cstr[0] == '_' && mangled_name_cstr[1] == 'Z' && + (mangled_name_cstr[2] != 'T' && // avoid virtual table, VTT structure, + // typeinfo structure, and typeinfo + // mangled_name + mangled_name_cstr[2] != 'G' && // avoid guard variables + mangled_name_cstr[2] != 'Z')) // named local entities (if we + // eventually handle eSymbolTypeData, + // we will want this back) + { + CPlusPlusLanguage::MethodName cxx_method(demangled_name); + if (!cxx_method.GetBasename().empty()) { + std::string shortname; + if (!cxx_method.GetContext().empty()) + shortname = cxx_method.GetContext().str() + "::"; + shortname += cxx_method.GetBasename().str(); + return ConstString(shortname); + } + } + } + if (demangled_name) + return demangled_name; + return mangled.GetMangledName(); } -uint32_t CPlusPlusLanguage::GetPluginVersion() { return 1; } - // Static Functions Language *CPlusPlusLanguage::CreateInstance(lldb::LanguageType language) { @@ -303,13 +321,12 @@ class ManglingSubstitutor public: ManglingSubstitutor() : Base(nullptr, nullptr) {} - template<typename... Ts> + template <typename... Ts> ConstString substitute(llvm::StringRef Mangled, Ts &&... Vals) { this->getDerived().reset(Mangled, std::forward<Ts>(Vals)...); return substituteImpl(Mangled); } - protected: void reset(llvm::StringRef Mangled) { Base::reset(Mangled.begin(), Mangled.end()); @@ -363,7 +380,6 @@ private: llvm::StringRef(Written, std::distance(Written, currentParserPos())); Written = currentParserPos(); } - }; /// Given a mangled function `Mangled`, replace all the primitive function type @@ -397,9 +413,10 @@ public: }; } // namespace -uint32_t CPlusPlusLanguage::FindAlternateFunctionManglings( - const ConstString mangled_name, std::set<ConstString> &alternates) { - const auto start_size = alternates.size(); +std::vector<ConstString> CPlusPlusLanguage::GenerateAlternateFunctionManglings( + const ConstString mangled_name) const { + std::vector<ConstString> alternates; + /// Get a basic set of alternative manglings for the given symbol `name`, by /// making a few basic possible substitutions on basic types, storage duration /// and `const`ness for the given symbol. The output parameter `alternates` @@ -412,7 +429,7 @@ uint32_t CPlusPlusLanguage::FindAlternateFunctionManglings( strncmp(mangled_name.GetCString(), "_ZNK", 4)) { std::string fixed_scratch("_ZNK"); fixed_scratch.append(mangled_name.GetCString() + 3); - alternates.insert(ConstString(fixed_scratch)); + alternates.push_back(ConstString(fixed_scratch)); } // Maybe we're looking for a static symbol but we thought it was global... @@ -420,7 +437,7 @@ uint32_t CPlusPlusLanguage::FindAlternateFunctionManglings( strncmp(mangled_name.GetCString(), "_ZL", 3)) { std::string fixed_scratch("_ZL"); fixed_scratch.append(mangled_name.GetCString() + 2); - alternates.insert(ConstString(fixed_scratch)); + alternates.push_back(ConstString(fixed_scratch)); } TypeSubstitutor TS; @@ -430,24 +447,74 @@ uint32_t CPlusPlusLanguage::FindAlternateFunctionManglings( // parameter, try finding matches which have the general case 'c'. if (ConstString char_fixup = TS.substitute(mangled_name.GetStringRef(), "a", "c")) - alternates.insert(char_fixup); + alternates.push_back(char_fixup); // long long parameter mangling 'x', may actually just be a long 'l' argument if (ConstString long_fixup = TS.substitute(mangled_name.GetStringRef(), "x", "l")) - alternates.insert(long_fixup); + alternates.push_back(long_fixup); // unsigned long long parameter mangling 'y', may actually just be unsigned // long 'm' argument if (ConstString ulong_fixup = TS.substitute(mangled_name.GetStringRef(), "y", "m")) - alternates.insert(ulong_fixup); + alternates.push_back(ulong_fixup); if (ConstString ctor_fixup = CtorDtorSubstitutor().substitute(mangled_name.GetStringRef())) - alternates.insert(ctor_fixup); + alternates.push_back(ctor_fixup); - return alternates.size() - start_size; + return alternates; +} + +ConstString CPlusPlusLanguage::FindBestAlternateFunctionMangledName( + const Mangled mangled, const SymbolContext &sym_ctx) const { + ConstString demangled = mangled.GetDemangledName(); + if (!demangled) + return ConstString(); + + CPlusPlusLanguage::MethodName cpp_name(demangled); + std::string scope_qualified_name = cpp_name.GetScopeQualifiedName(); + + if (!scope_qualified_name.size()) + return ConstString(); + + if (!sym_ctx.module_sp) + return ConstString(); + + lldb_private::SymbolFile *sym_file = sym_ctx.module_sp->GetSymbolFile(); + if (!sym_file) + return ConstString(); + + std::vector<ConstString> alternates; + sym_file->GetMangledNamesForFunction(scope_qualified_name, alternates); + + std::vector<ConstString> param_and_qual_matches; + std::vector<ConstString> param_matches; + for (size_t i = 0; i < alternates.size(); i++) { + ConstString alternate_mangled_name = alternates[i]; + Mangled mangled(alternate_mangled_name); + ConstString demangled = mangled.GetDemangledName(); + + CPlusPlusLanguage::MethodName alternate_cpp_name(demangled); + if (!cpp_name.IsValid()) + continue; + + if (alternate_cpp_name.GetArguments() == cpp_name.GetArguments()) { + if (alternate_cpp_name.GetQualifiers() == cpp_name.GetQualifiers()) + param_and_qual_matches.push_back(alternate_mangled_name); + else + param_matches.push_back(alternate_mangled_name); + } + } + + if (param_and_qual_matches.size()) + return param_and_qual_matches[0]; // It is assumed that there will be only + // one! + else if (param_matches.size()) + return param_matches[0]; // Return one of them as a best match + else + return ConstString(); } static void LoadLibCxxFormatters(lldb::TypeCategoryImplSP cpp_category_sp) { @@ -486,26 +553,23 @@ static void LoadLibCxxFormatters(lldb::TypeCategoryImplSP cpp_category_sp) { AddCXXSummary(cpp_category_sp, lldb_private::formatters::LibcxxStringSummaryProviderUTF16, "std::u16string summary provider", - ConstString( - "^std::__[[:alnum:]]+::basic_string<char16_t, " - "std::__[[:alnum:]]+::char_traits<char16_t>, " - "std::__[[:alnum:]]+::allocator<char16_t> >$"), + ConstString("^std::__[[:alnum:]]+::basic_string<char16_t, " + "std::__[[:alnum:]]+::char_traits<char16_t>, " + "std::__[[:alnum:]]+::allocator<char16_t> >$"), stl_summary_flags, true); AddCXXSummary(cpp_category_sp, lldb_private::formatters::LibcxxStringSummaryProviderUTF32, "std::u32string summary provider", - ConstString( - "^std::__[[:alnum:]]+::basic_string<char32_t, " - "std::__[[:alnum:]]+::char_traits<char32_t>, " - "std::__[[:alnum:]]+::allocator<char32_t> >$"), + ConstString("^std::__[[:alnum:]]+::basic_string<char32_t, " + "std::__[[:alnum:]]+::char_traits<char32_t>, " + "std::__[[:alnum:]]+::allocator<char32_t> >$"), stl_summary_flags, true); - AddCXXSummary(cpp_category_sp, - lldb_private::formatters::LibcxxWStringSummaryProvider, - "std::wstring summary provider", - ConstString("^std::__[[:alnum:]]+::wstring$"), - stl_summary_flags, true); + AddCXXSummary( + cpp_category_sp, lldb_private::formatters::LibcxxWStringSummaryProvider, + "std::wstring summary provider", + ConstString("^std::__[[:alnum:]]+::wstring$"), stl_summary_flags, true); AddCXXSummary(cpp_category_sp, lldb_private::formatters::LibcxxWStringSummaryProvider, "std::wstring summary provider", @@ -702,11 +766,11 @@ static void LoadLibCxxFormatters(lldb::TypeCategoryImplSP cpp_category_sp) { "libc++ std::tuple summary provider", ConstString("^std::__[[:alnum:]]+::tuple<.*>(( )?&)?$"), stl_summary_flags, true); - AddCXXSummary( - cpp_category_sp, lldb_private::formatters::LibCxxAtomicSummaryProvider, - "libc++ std::atomic summary provider", - ConstString("^std::__[[:alnum:]]+::atomic<.+>$"), stl_summary_flags, - true); + AddCXXSummary(cpp_category_sp, + lldb_private::formatters::LibCxxAtomicSummaryProvider, + "libc++ std::atomic summary provider", + ConstString("^std::__[[:alnum:]]+::atomic<.+>$"), + stl_summary_flags, true); AddCXXSummary(cpp_category_sp, lldb_private::formatters::LibcxxOptionalSummaryProvider, "libc++ std::optional summary provider", @@ -793,7 +857,8 @@ static void LoadLibStdcppFormatters(lldb::TypeCategoryImplSP cpp_category_sp) { "std::allocator<char> >"), cxx11_string_summary_sp); cpp_category_sp->GetTypeSummariesContainer()->Add( - ConstString("std::__cxx11::basic_string<unsigned char, std::char_traits<unsigned char>, " + ConstString("std::__cxx11::basic_string<unsigned char, " + "std::char_traits<unsigned char>, " "std::allocator<unsigned char> >"), cxx11_string_summary_sp); @@ -825,6 +890,8 @@ static void LoadLibStdcppFormatters(lldb::TypeCategoryImplSP cpp_category_sp) { SyntheticChildren::Flags stl_synth_flags; stl_synth_flags.SetCascades(true).SetSkipPointers(false).SetSkipReferences( false); + SyntheticChildren::Flags stl_deref_flags = stl_synth_flags; + stl_deref_flags.SetFrontEndWantsDereference(); cpp_category_sp->GetRegexTypeSyntheticsContainer()->Add( RegularExpression("^std::vector<.+>(( )?&)?$"), @@ -835,14 +902,38 @@ static void LoadLibStdcppFormatters(lldb::TypeCategoryImplSP cpp_category_sp) { RegularExpression("^std::map<.+> >(( )?&)?$"), SyntheticChildrenSP(new ScriptedSyntheticChildren( stl_synth_flags, - "lldb.formatters.cpp.gnu_libstdcpp.StdMapSynthProvider"))); + "lldb.formatters.cpp.gnu_libstdcpp.StdMapLikeSynthProvider"))); + cpp_category_sp->GetRegexTypeSyntheticsContainer()->Add( + RegularExpression("^std::set<.+> >(( )?&)?$"), + SyntheticChildrenSP(new ScriptedSyntheticChildren( + stl_deref_flags, + "lldb.formatters.cpp.gnu_libstdcpp.StdMapLikeSynthProvider"))); + cpp_category_sp->GetRegexTypeSyntheticsContainer()->Add( + RegularExpression("^std::multimap<.+> >(( )?&)?$"), + SyntheticChildrenSP(new ScriptedSyntheticChildren( + stl_deref_flags, + "lldb.formatters.cpp.gnu_libstdcpp.StdMapLikeSynthProvider"))); + cpp_category_sp->GetRegexTypeSyntheticsContainer()->Add( + RegularExpression("^std::multiset<.+> >(( )?&)?$"), + SyntheticChildrenSP(new ScriptedSyntheticChildren( + stl_deref_flags, + "lldb.formatters.cpp.gnu_libstdcpp.StdMapLikeSynthProvider"))); cpp_category_sp->GetRegexTypeSyntheticsContainer()->Add( RegularExpression("^std::(__cxx11::)?list<.+>(( )?&)?$"), SyntheticChildrenSP(new ScriptedSyntheticChildren( stl_synth_flags, "lldb.formatters.cpp.gnu_libstdcpp.StdListSynthProvider"))); + cpp_category_sp->GetRegexTypeSyntheticsContainer()->Add( + RegularExpression("^std::(__cxx11::)?forward_list<.+>(( )?&)?$"), + SyntheticChildrenSP(new ScriptedSyntheticChildren( + stl_synth_flags, + "lldb.formatters.cpp.gnu_libstdcpp.StdForwardListSynthProvider"))); stl_summary_flags.SetDontShowChildren(false); - stl_summary_flags.SetSkipPointers(true); + stl_summary_flags.SetSkipPointers(false); + cpp_category_sp->GetRegexTypeSummariesContainer()->Add( + RegularExpression("^std::bitset<.+>(( )?&)?$"), + TypeSummaryImplSP( + new StringSummaryFormat(stl_summary_flags, "size=${svar%#}"))); cpp_category_sp->GetRegexTypeSummariesContainer()->Add( RegularExpression("^std::vector<.+>(( )?&)?$"), TypeSummaryImplSP( @@ -852,9 +943,25 @@ static void LoadLibStdcppFormatters(lldb::TypeCategoryImplSP cpp_category_sp) { TypeSummaryImplSP( new StringSummaryFormat(stl_summary_flags, "size=${svar%#}"))); cpp_category_sp->GetRegexTypeSummariesContainer()->Add( + RegularExpression("^std::set<.+> >(( )?&)?$"), + TypeSummaryImplSP( + new StringSummaryFormat(stl_summary_flags, "size=${svar%#}"))); + cpp_category_sp->GetRegexTypeSummariesContainer()->Add( + RegularExpression("^std::multimap<.+> >(( )?&)?$"), + TypeSummaryImplSP( + new StringSummaryFormat(stl_summary_flags, "size=${svar%#}"))); + cpp_category_sp->GetRegexTypeSummariesContainer()->Add( + RegularExpression("^std::multiset<.+> >(( )?&)?$"), + TypeSummaryImplSP( + new StringSummaryFormat(stl_summary_flags, "size=${svar%#}"))); + cpp_category_sp->GetRegexTypeSummariesContainer()->Add( RegularExpression("^std::(__cxx11::)?list<.+>(( )?&)?$"), TypeSummaryImplSP( new StringSummaryFormat(stl_summary_flags, "size=${svar%#}"))); + cpp_category_sp->GetRegexTypeSummariesContainer()->Add( + RegularExpression("^std::(__cxx11::)?forward_list<.+>(( )?&)?$"), + TypeSummaryImplSP( + new StringSummaryFormat(stl_summary_flags, "size=${svar%#}"))); AddCXXSynthetic( cpp_category_sp, @@ -889,6 +996,12 @@ static void LoadLibStdcppFormatters(lldb::TypeCategoryImplSP cpp_category_sp) { "std::tuple synthetic children", ConstString("^std::tuple<.+>(( )?&)?$"), stl_synth_flags, true); + AddCXXSynthetic( + cpp_category_sp, + lldb_private::formatters::LibStdcppBitsetSyntheticFrontEndCreator, + "std::bitset synthetic child", ConstString("^std::bitset<.+>(( )?&)?$"), + stl_deref_flags, true); + AddCXXSummary(cpp_category_sp, lldb_private::formatters::LibStdcppUniquePointerSummaryProvider, "libstdc++ std::unique_ptr summary provider", @@ -928,15 +1041,13 @@ static void LoadSystemFormatters(lldb::TypeCategoryImplSP cpp_category_sp) { .SetShowMembersOneLiner(false) .SetHideItemNames(false); - // FIXME because of a bug in the FormattersContainer we need to add a summary - // for both X* and const X* (<rdar://problem/12717717>) AddCXXSummary( cpp_category_sp, lldb_private::formatters::Char8StringSummaryProvider, "char8_t * summary provider", ConstString("char8_t *"), string_flags); AddCXXSummary(cpp_category_sp, lldb_private::formatters::Char8StringSummaryProvider, "char8_t [] summary provider", - ConstString("char8_t \\[[0-9]+\\]"), string_array_flags, true); + ConstString("char8_t ?\\[[0-9]+\\]"), string_array_flags, true); AddCXXSummary( cpp_category_sp, lldb_private::formatters::Char16StringSummaryProvider, @@ -944,7 +1055,7 @@ static void LoadSystemFormatters(lldb::TypeCategoryImplSP cpp_category_sp) { AddCXXSummary(cpp_category_sp, lldb_private::formatters::Char16StringSummaryProvider, "char16_t [] summary provider", - ConstString("char16_t \\[[0-9]+\\]"), string_array_flags, true); + ConstString("char16_t ?\\[[0-9]+\\]"), string_array_flags, true); AddCXXSummary( cpp_category_sp, lldb_private::formatters::Char32StringSummaryProvider, @@ -952,7 +1063,7 @@ static void LoadSystemFormatters(lldb::TypeCategoryImplSP cpp_category_sp) { AddCXXSummary(cpp_category_sp, lldb_private::formatters::Char32StringSummaryProvider, "char32_t [] summary provider", - ConstString("char32_t \\[[0-9]+\\]"), string_array_flags, true); + ConstString("char32_t ?\\[[0-9]+\\]"), string_array_flags, true); AddCXXSummary( cpp_category_sp, lldb_private::formatters::WCharStringSummaryProvider, @@ -960,7 +1071,7 @@ static void LoadSystemFormatters(lldb::TypeCategoryImplSP cpp_category_sp) { AddCXXSummary(cpp_category_sp, lldb_private::formatters::WCharStringSummaryProvider, "wchar_t * summary provider", - ConstString("wchar_t \\[[0-9]+\\]"), string_array_flags, true); + ConstString("wchar_t ?\\[[0-9]+\\]"), string_array_flags, true); AddCXXSummary( cpp_category_sp, lldb_private::formatters::Char16StringSummaryProvider, @@ -1015,7 +1126,8 @@ lldb::TypeCategoryImplSP CPlusPlusLanguage::GetFormatters() { static TypeCategoryImplSP g_category; llvm::call_once(g_initialize, [this]() -> void { - DataVisualization::Categories::GetCategory(GetPluginName(), g_category); + DataVisualization::Categories::GetCategory(ConstString(GetPluginName()), + g_category); if (g_category) { LoadLibStdcppFormatters(g_category); LoadLibCxxFormatters(g_category); @@ -1097,9 +1209,8 @@ CPlusPlusLanguage::GetHardcodedSynthetics() { llvm::call_once(g_initialize, []() -> void { g_formatters.push_back([](lldb_private::ValueObject &valobj, - lldb::DynamicValueType, - FormatManager & - fmt_mgr) -> SyntheticChildren::SharedPointer { + lldb::DynamicValueType, FormatManager &fmt_mgr) + -> SyntheticChildren::SharedPointer { static CXXSyntheticChildren::SharedPointer formatter_sp( new CXXSyntheticChildren( SyntheticChildren::Flags() @@ -1116,9 +1227,8 @@ CPlusPlusLanguage::GetHardcodedSynthetics() { return nullptr; }); g_formatters.push_back([](lldb_private::ValueObject &valobj, - lldb::DynamicValueType, - FormatManager & - fmt_mgr) -> SyntheticChildren::SharedPointer { + lldb::DynamicValueType, FormatManager &fmt_mgr) + -> SyntheticChildren::SharedPointer { static CXXSyntheticChildren::SharedPointer formatter_sp( new CXXSyntheticChildren( SyntheticChildren::Flags() @@ -1133,7 +1243,6 @@ CPlusPlusLanguage::GetHardcodedSynthetics() { } return nullptr; }); - }); return g_formatters; diff --git a/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.h b/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.h index 9163be4807ec..5547864a3763 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.h +++ b/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.h @@ -102,10 +102,13 @@ public: static lldb_private::Language *CreateInstance(lldb::LanguageType language); - static lldb_private::ConstString GetPluginNameStatic(); + static llvm::StringRef GetPluginNameStatic() { return "cplusplus"; } bool SymbolNameFitsToLanguage(Mangled mangled) const override; + ConstString + GetDemangledFunctionNameWithoutArguments(Mangled mangled) const override; + static bool IsCPPMangledName(llvm::StringRef name); // Extract C++ context and identifier from a string using heuristic matching @@ -124,16 +127,14 @@ public: llvm::StringRef &context, llvm::StringRef &identifier); - // Given a mangled function name, calculates some alternative manglings since - // the compiler mangling may not line up with the symbol we are expecting - static uint32_t - FindAlternateFunctionManglings(const ConstString mangled, - std::set<ConstString> &candidates); + std::vector<ConstString> + GenerateAlternateFunctionManglings(const ConstString mangled) const override; - // PluginInterface protocol - ConstString GetPluginName() override; + ConstString FindBestAlternateFunctionMangledName( + const Mangled mangled, const SymbolContext &sym_ctx) const override; - uint32_t GetPluginVersion() override; + // PluginInterface protocol + llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); } }; } // namespace lldb_private diff --git a/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/CxxStringTypes.cpp b/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/CxxStringTypes.cpp index 41bbd2b01a1e..535a9f6015d8 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/CxxStringTypes.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/CxxStringTypes.cpp @@ -32,89 +32,87 @@ using namespace lldb; using namespace lldb_private; using namespace lldb_private::formatters; -bool lldb_private::formatters::Char8StringSummaryProvider( - ValueObject &valobj, Stream &stream, const TypeSummaryOptions &) { - ProcessSP process_sp = valobj.GetProcessSP(); - if (!process_sp) - return false; +using StringElementType = StringPrinter::StringElementType; + +static constexpr std::pair<const char *, Format> +getElementTraits(StringElementType ElemType) { + switch (ElemType) { + case StringElementType::UTF8: + return std::make_pair("u8", lldb::eFormatUnicode8); + case StringElementType::UTF16: + return std::make_pair("u", lldb::eFormatUnicode16); + case StringElementType::UTF32: + return std::make_pair("U", lldb::eFormatUnicode32); + default: + return std::make_pair(nullptr, lldb::eFormatInvalid); + } +} - lldb::addr_t valobj_addr = GetArrayAddressOrPointerValue(valobj); - if (valobj_addr == 0 || valobj_addr == LLDB_INVALID_ADDRESS) +template <StringElementType ElemType> +static bool CharStringSummaryProvider(ValueObject &valobj, Stream &stream) { + Address valobj_addr = GetArrayAddressOrPointerValue(valobj); + if (!valobj_addr.IsValid()) return false; StringPrinter::ReadStringAndDumpToStreamOptions options(valobj); options.SetLocation(valobj_addr); - options.SetProcessSP(process_sp); + options.SetTargetSP(valobj.GetTargetSP()); options.SetStream(&stream); - options.SetPrefixToken("u8"); + options.SetPrefixToken(getElementTraits(ElemType).first); - if (!StringPrinter::ReadStringAndDumpToStream< - StringPrinter::StringElementType::UTF8>(options)) { + if (!StringPrinter::ReadStringAndDumpToStream<ElemType>(options)) stream.Printf("Summary Unavailable"); - return true; - } return true; } -bool lldb_private::formatters::Char16StringSummaryProvider( - ValueObject &valobj, Stream &stream, const TypeSummaryOptions &) { - ProcessSP process_sp = valobj.GetProcessSP(); - if (!process_sp) - return false; +template <StringElementType ElemType> +static bool CharSummaryProvider(ValueObject &valobj, Stream &stream) { + DataExtractor data; + Status error; + valobj.GetData(data, error); - lldb::addr_t valobj_addr = GetArrayAddressOrPointerValue(valobj); - if (valobj_addr == 0 || valobj_addr == LLDB_INVALID_ADDRESS) + if (error.Fail()) return false; - StringPrinter::ReadStringAndDumpToStreamOptions options(valobj); - options.SetLocation(valobj_addr); - options.SetProcessSP(process_sp); - options.SetStream(&stream); - options.SetPrefixToken("u"); + std::string value; + StringPrinter::ReadBufferAndDumpToStreamOptions options(valobj); - if (!StringPrinter::ReadStringAndDumpToStream< - StringPrinter::StringElementType::UTF16>(options)) { - stream.Printf("Summary Unavailable"); - return true; - } + constexpr auto ElemTraits = getElementTraits(ElemType); + valobj.GetValueAsCString(ElemTraits.second, value); - return true; -} + if (!value.empty()) + stream.Printf("%s ", value.c_str()); -bool lldb_private::formatters::Char32StringSummaryProvider( - ValueObject &valobj, Stream &stream, const TypeSummaryOptions &) { - ProcessSP process_sp = valobj.GetProcessSP(); - if (!process_sp) - return false; + options.SetData(std::move(data)); + options.SetStream(&stream); + options.SetPrefixToken(ElemTraits.first); + options.SetQuote('\''); + options.SetSourceSize(1); + options.SetBinaryZeroIsTerminator(false); - lldb::addr_t valobj_addr = GetArrayAddressOrPointerValue(valobj); - if (valobj_addr == 0 || valobj_addr == LLDB_INVALID_ADDRESS) - return false; + return StringPrinter::ReadBufferAndDumpToStream<ElemType>(options); +} - StringPrinter::ReadStringAndDumpToStreamOptions options(valobj); - options.SetLocation(valobj_addr); - options.SetProcessSP(process_sp); - options.SetStream(&stream); - options.SetPrefixToken("U"); +bool lldb_private::formatters::Char8StringSummaryProvider( + ValueObject &valobj, Stream &stream, const TypeSummaryOptions &) { + return CharStringSummaryProvider<StringElementType::UTF8>(valobj, stream); +} - if (!StringPrinter::ReadStringAndDumpToStream< - StringPrinter::StringElementType::UTF32>(options)) { - stream.Printf("Summary Unavailable"); - return true; - } +bool lldb_private::formatters::Char16StringSummaryProvider( + ValueObject &valobj, Stream &stream, const TypeSummaryOptions &) { + return CharStringSummaryProvider<StringElementType::UTF16>(valobj, stream); +} - return true; +bool lldb_private::formatters::Char32StringSummaryProvider( + ValueObject &valobj, Stream &stream, const TypeSummaryOptions &) { + return CharStringSummaryProvider<StringElementType::UTF32>(valobj, stream); } bool lldb_private::formatters::WCharStringSummaryProvider( ValueObject &valobj, Stream &stream, const TypeSummaryOptions &) { - ProcessSP process_sp = valobj.GetProcessSP(); - if (!process_sp) - return false; - - lldb::addr_t valobj_addr = GetArrayAddressOrPointerValue(valobj); - if (valobj_addr == 0 || valobj_addr == LLDB_INVALID_ADDRESS) + Address valobj_addr = GetArrayAddressOrPointerValue(valobj); + if (!valobj_addr.IsValid()) return false; // Get a wchar_t basic type from the current type system @@ -132,20 +130,20 @@ bool lldb_private::formatters::WCharStringSummaryProvider( StringPrinter::ReadStringAndDumpToStreamOptions options(valobj); options.SetLocation(valobj_addr); - options.SetProcessSP(process_sp); + options.SetTargetSP(valobj.GetTargetSP()); options.SetStream(&stream); options.SetPrefixToken("L"); switch (wchar_size) { case 8: - return StringPrinter::ReadStringAndDumpToStream< - StringPrinter::StringElementType::UTF8>(options); + return StringPrinter::ReadStringAndDumpToStream<StringElementType::UTF8>( + options); case 16: - return StringPrinter::ReadStringAndDumpToStream< - StringPrinter::StringElementType::UTF16>(options); + return StringPrinter::ReadStringAndDumpToStream<StringElementType::UTF16>( + options); case 32: - return StringPrinter::ReadStringAndDumpToStream< - StringPrinter::StringElementType::UTF32>(options); + return StringPrinter::ReadStringAndDumpToStream<StringElementType::UTF32>( + options); default: stream.Printf("size for wchar_t is not valid"); return true; @@ -155,80 +153,17 @@ bool lldb_private::formatters::WCharStringSummaryProvider( bool lldb_private::formatters::Char8SummaryProvider( ValueObject &valobj, Stream &stream, const TypeSummaryOptions &) { - DataExtractor data; - Status error; - valobj.GetData(data, error); - - if (error.Fail()) - return false; - - std::string value; - valobj.GetValueAsCString(lldb::eFormatUnicode8, value); - if (!value.empty()) - stream.Printf("%s ", value.c_str()); - - StringPrinter::ReadBufferAndDumpToStreamOptions options(valobj); - options.SetData(data); - options.SetStream(&stream); - options.SetPrefixToken("u8"); - options.SetQuote('\''); - options.SetSourceSize(1); - options.SetBinaryZeroIsTerminator(false); - - return StringPrinter::ReadBufferAndDumpToStream< - StringPrinter::StringElementType::UTF8>(options); + return CharSummaryProvider<StringElementType::UTF8>(valobj, stream); } bool lldb_private::formatters::Char16SummaryProvider( ValueObject &valobj, Stream &stream, const TypeSummaryOptions &) { - DataExtractor data; - Status error; - valobj.GetData(data, error); - - if (error.Fail()) - return false; - - std::string value; - valobj.GetValueAsCString(lldb::eFormatUnicode16, value); - if (!value.empty()) - stream.Printf("%s ", value.c_str()); - - StringPrinter::ReadBufferAndDumpToStreamOptions options(valobj); - options.SetData(data); - options.SetStream(&stream); - options.SetPrefixToken("u"); - options.SetQuote('\''); - options.SetSourceSize(1); - options.SetBinaryZeroIsTerminator(false); - - return StringPrinter::ReadBufferAndDumpToStream< - StringPrinter::StringElementType::UTF16>(options); + return CharSummaryProvider<StringElementType::UTF16>(valobj, stream); } bool lldb_private::formatters::Char32SummaryProvider( ValueObject &valobj, Stream &stream, const TypeSummaryOptions &) { - DataExtractor data; - Status error; - valobj.GetData(data, error); - - if (error.Fail()) - return false; - - std::string value; - valobj.GetValueAsCString(lldb::eFormatUnicode32, value); - if (!value.empty()) - stream.Printf("%s ", value.c_str()); - - StringPrinter::ReadBufferAndDumpToStreamOptions options(valobj); - options.SetData(data); - options.SetStream(&stream); - options.SetPrefixToken("U"); - options.SetQuote('\''); - options.SetSourceSize(1); - options.SetBinaryZeroIsTerminator(false); - - return StringPrinter::ReadBufferAndDumpToStream< - StringPrinter::StringElementType::UTF32>(options); + return CharSummaryProvider<StringElementType::UTF32>(valobj, stream); } bool lldb_private::formatters::WCharSummaryProvider( @@ -254,7 +189,7 @@ bool lldb_private::formatters::WCharSummaryProvider( const uint32_t wchar_size = *size; StringPrinter::ReadBufferAndDumpToStreamOptions options(valobj); - options.SetData(data); + options.SetData(std::move(data)); options.SetStream(&stream); options.SetPrefixToken("L"); options.SetQuote('\''); @@ -263,14 +198,14 @@ bool lldb_private::formatters::WCharSummaryProvider( switch (wchar_size) { case 8: - return StringPrinter::ReadBufferAndDumpToStream< - StringPrinter::StringElementType::UTF8>(options); + return StringPrinter::ReadBufferAndDumpToStream<StringElementType::UTF8>( + options); case 16: - return StringPrinter::ReadBufferAndDumpToStream< - StringPrinter::StringElementType::UTF16>(options); + return StringPrinter::ReadBufferAndDumpToStream<StringElementType::UTF16>( + options); case 32: - return StringPrinter::ReadBufferAndDumpToStream< - StringPrinter::StringElementType::UTF32>(options); + return StringPrinter::ReadBufferAndDumpToStream<StringElementType::UTF32>( + options); default: stream.Printf("size for wchar_t is not valid"); return true; diff --git a/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibCxxBitset.cpp b/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/GenericBitset.cpp index e5b868fc0fce..fc8255983436 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibCxxBitset.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/GenericBitset.cpp @@ -1,4 +1,4 @@ -//===-- LibCxxBitset.cpp --------------------------------------------------===// +//===-- GenericBitset.cpp //-----------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -7,6 +7,7 @@ //===----------------------------------------------------------------------===// #include "LibCxx.h" +#include "LibStdcpp.h" #include "Plugins/TypeSystem/Clang/TypeSystemClang.h" #include "lldb/DataFormatters/FormattersHelpers.h" #include "lldb/Target/Target.h" @@ -16,9 +17,15 @@ using namespace lldb_private; namespace { -class BitsetFrontEnd : public SyntheticChildrenFrontEnd { +/// This class can be used for handling bitsets from both libcxx and libstdcpp. +class GenericBitsetFrontEnd : public SyntheticChildrenFrontEnd { public: - BitsetFrontEnd(ValueObject &valobj); + enum class StdLib { + LibCxx, + LibStdcpp, + }; + + GenericBitsetFrontEnd(ValueObject &valobj, StdLib stdlib); size_t GetIndexOfChildWithName(ConstString name) override { return formatters::ExtractIndexFromString(name.GetCString()); @@ -30,6 +37,8 @@ public: ValueObjectSP GetChildAtIndex(size_t idx) override; private: + ConstString GetDataContainerMemberName(); + // The lifetime of a ValueObject and all its derivative ValueObjects // (children, clones, etc.) is managed by a ClusterManager. These // objects are only destroyed when every shared pointer to any of them @@ -38,15 +47,16 @@ private: // Value objects created from raw data (i.e. in a different cluster) must // be referenced via shared pointer to keep them alive, however. std::vector<ValueObjectSP> m_elements; - ValueObject* m_first = nullptr; + ValueObject *m_first = nullptr; CompilerType m_bool_type; ByteOrder m_byte_order = eByteOrderInvalid; uint8_t m_byte_size = 0; + StdLib m_stdlib; }; } // namespace -BitsetFrontEnd::BitsetFrontEnd(ValueObject &valobj) - : SyntheticChildrenFrontEnd(valobj) { +GenericBitsetFrontEnd::GenericBitsetFrontEnd(ValueObject &valobj, StdLib stdlib) + : SyntheticChildrenFrontEnd(valobj), m_stdlib(stdlib) { m_bool_type = valobj.GetCompilerType().GetBasicTypeFromAST(eBasicTypeBool); if (auto target_sp = m_backend.GetTargetSP()) { m_byte_order = target_sp->GetArchitecture().GetByteOrder(); @@ -55,7 +65,16 @@ BitsetFrontEnd::BitsetFrontEnd(ValueObject &valobj) } } -bool BitsetFrontEnd::Update() { +ConstString GenericBitsetFrontEnd::GetDataContainerMemberName() { + switch (m_stdlib) { + case StdLib::LibCxx: + return ConstString("__first_"); + case StdLib::LibStdcpp: + return ConstString("_M_w"); + } +} + +bool GenericBitsetFrontEnd::Update() { m_elements.clear(); m_first = nullptr; @@ -65,16 +84,17 @@ bool BitsetFrontEnd::Update() { size_t capping_size = target_sp->GetMaximumNumberOfChildrenToDisplay(); size_t size = 0; + if (auto arg = m_backend.GetCompilerType().GetIntegralTemplateArgument(0)) size = arg->value.getLimitedValue(capping_size); m_elements.assign(size, ValueObjectSP()); - - m_first = m_backend.GetChildMemberWithName(ConstString("__first_"), true).get(); + m_first = m_backend.GetChildMemberWithName(GetDataContainerMemberName(), true) + .get(); return false; } -ValueObjectSP BitsetFrontEnd::GetChildAtIndex(size_t idx) { +ValueObjectSP GenericBitsetFrontEnd::GetChildAtIndex(size_t idx) { if (idx >= m_elements.size() || !m_first) return ValueObjectSP(); @@ -112,9 +132,18 @@ ValueObjectSP BitsetFrontEnd::GetChildAtIndex(size_t idx) { return m_elements[idx]; } +SyntheticChildrenFrontEnd *formatters::LibStdcppBitsetSyntheticFrontEndCreator( + CXXSyntheticChildren *, lldb::ValueObjectSP valobj_sp) { + if (valobj_sp) + return new GenericBitsetFrontEnd(*valobj_sp, + GenericBitsetFrontEnd::StdLib::LibStdcpp); + return nullptr; +} + SyntheticChildrenFrontEnd *formatters::LibcxxBitsetSyntheticFrontEndCreator( CXXSyntheticChildren *, lldb::ValueObjectSP valobj_sp) { if (valobj_sp) - return new BitsetFrontEnd(*valobj_sp); + return new GenericBitsetFrontEnd(*valobj_sp, + GenericBitsetFrontEnd::StdLib::LibCxx); return nullptr; } diff --git a/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp b/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp index 8eda422f3145..b9aef0ae7d9e 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp @@ -686,7 +686,7 @@ bool lldb_private::formatters::LibcxxWStringSummaryProvider( if (!wchar_t_size) return false; - options.SetData(extractor); + options.SetData(std::move(extractor)); options.SetStream(&stream); options.SetPrefixToken("L"); options.SetQuote('"'); @@ -743,12 +743,14 @@ bool LibcxxStringSummaryProvider(ValueObject &valobj, Stream &stream, } } - DataExtractor extractor; - const size_t bytes_read = location_sp->GetPointeeData(extractor, 0, size); - if (bytes_read < size) - return false; + { + DataExtractor extractor; + const size_t bytes_read = location_sp->GetPointeeData(extractor, 0, size); + if (bytes_read < size) + return false; - options.SetData(extractor); + options.SetData(std::move(extractor)); + } options.SetStream(&stream); if (prefix_token.empty()) options.SetPrefixToken(nullptr); diff --git a/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibStdcpp.cpp b/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibStdcpp.cpp index b4af67ecee0d..9e248d162cd2 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibStdcpp.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibStdcpp.cpp @@ -250,7 +250,7 @@ bool lldb_private::formatters::LibStdcppStringSummaryProvider( addr_of_data == LLDB_INVALID_ADDRESS) return false; options.SetLocation(addr_of_data); - options.SetProcessSP(process_sp); + options.SetTargetSP(valobj.GetTargetSP()); options.SetStream(&stream); options.SetNeedsZeroTermination(false); options.SetBinaryZeroIsTerminator(true); @@ -311,7 +311,7 @@ bool lldb_private::formatters::LibStdcppWStringSummaryProvider( addr_of_data == LLDB_INVALID_ADDRESS) return false; options.SetLocation(addr_of_data); - options.SetProcessSP(process_sp); + options.SetTargetSP(valobj.GetTargetSP()); options.SetStream(&stream); options.SetNeedsZeroTermination(false); options.SetBinaryZeroIsTerminator(false); diff --git a/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibStdcpp.h b/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibStdcpp.h index 9e41aa0ffc01..b6f9c469fedd 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibStdcpp.h +++ b/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibStdcpp.h @@ -42,6 +42,10 @@ LibStdcppTupleSyntheticFrontEndCreator(CXXSyntheticChildren *, lldb::ValueObjectSP); SyntheticChildrenFrontEnd * +LibStdcppBitsetSyntheticFrontEndCreator(CXXSyntheticChildren *, + lldb::ValueObjectSP); + +SyntheticChildrenFrontEnd * LibStdcppVectorIteratorSyntheticFrontEndCreator(CXXSyntheticChildren *, lldb::ValueObjectSP); diff --git a/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/MSVCUndecoratedNameParser.cpp b/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/MSVCUndecoratedNameParser.cpp index b24bcc1344e2..8ecf6712eace 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/MSVCUndecoratedNameParser.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/MSVCUndecoratedNameParser.cpp @@ -72,7 +72,7 @@ MSVCUndecoratedNameParser::MSVCUndecoratedNameParser(llvm::StringRef name) { } bool MSVCUndecoratedNameParser::IsMSVCUndecoratedName(llvm::StringRef name) { - return name.find('`') != llvm::StringRef::npos; + return name.contains('`'); } bool MSVCUndecoratedNameParser::ExtractContextAndIdentifier( diff --git a/contrib/llvm-project/lldb/source/Plugins/Language/ObjC/Cocoa.cpp b/contrib/llvm-project/lldb/source/Plugins/Language/ObjC/Cocoa.cpp index 1479f4f0c151..0d7cd6791b04 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Language/ObjC/Cocoa.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Language/ObjC/Cocoa.cpp @@ -7,7 +7,10 @@ //===----------------------------------------------------------------------===// #include "Cocoa.h" +#include "NSString.h" +#include "ObjCConstants.h" +#include "Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.h" #include "Plugins/TypeSystem/Clang/TypeSystemClang.h" #include "lldb/Core/Mangled.h" #include "lldb/Core/ValueObject.h" @@ -28,9 +31,6 @@ #include "llvm/ADT/APInt.h" #include "llvm/ADT/bit.h" -#include "Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.h" - -#include "NSString.h" using namespace lldb; using namespace lldb_private; @@ -456,6 +456,72 @@ bool lldb_private::formatters::NSNumberSummaryProvider( if (class_name == "NSDecimalNumber") return NSDecimalNumberSummaryProvider(valobj, stream, options); + if (class_name == "NSConstantIntegerNumber") { + Status error; + int64_t value = process_sp->ReadSignedIntegerFromMemory( + valobj_addr + 2 * ptr_size, 8, 0, error); + if (error.Fail()) + return false; + uint64_t encoding_addr = process_sp->ReadUnsignedIntegerFromMemory( + valobj_addr + ptr_size, ptr_size, 0, error); + if (error.Fail()) + return false; + char encoding = + process_sp->ReadUnsignedIntegerFromMemory(encoding_addr, 1, 0, error); + if (error.Fail()) + return false; + + switch (encoding) { + case _C_CHR: + NSNumber_FormatChar(valobj, stream, (char)value, options.GetLanguage()); + return true; + case _C_SHT: + NSNumber_FormatShort(valobj, stream, (short)value, options.GetLanguage()); + return true; + case _C_INT: + NSNumber_FormatInt(valobj, stream, (int)value, options.GetLanguage()); + return true; + case _C_LNG: + case _C_LNG_LNG: + NSNumber_FormatLong(valobj, stream, value, options.GetLanguage()); + return true; + + case _C_UCHR: + case _C_USHT: + case _C_UINT: + case _C_ULNG: + case _C_ULNG_LNG: + stream.Printf("%" PRIu64, value); + return true; + } + + return false; + } + + if (class_name == "NSConstantFloatNumber") { + Status error; + uint32_t flt_as_int = process_sp->ReadUnsignedIntegerFromMemory( + valobj_addr + ptr_size, 4, 0, error); + if (error.Fail()) + return false; + float flt_value = 0.0f; + memcpy(&flt_value, &flt_as_int, sizeof(flt_as_int)); + NSNumber_FormatFloat(valobj, stream, flt_value, options.GetLanguage()); + return true; + } + + if (class_name == "NSConstantDoubleNumber") { + Status error; + uint64_t dbl_as_lng = process_sp->ReadUnsignedIntegerFromMemory( + valobj_addr + ptr_size, 8, 0, error); + if (error.Fail()) + return false; + double dbl_value = 0.0; + memcpy(&dbl_value, &dbl_as_lng, sizeof(dbl_as_lng)); + NSNumber_FormatDouble(valobj, stream, dbl_value, options.GetLanguage()); + return true; + } + if (class_name == "NSNumber" || class_name == "__NSCFNumber") { int64_t value = 0; uint64_t i_bits = 0; diff --git a/contrib/llvm-project/lldb/source/Plugins/Language/ObjC/NSArray.cpp b/contrib/llvm-project/lldb/source/Plugins/Language/ObjC/NSArray.cpp index b0398dd19c02..f18b59fb11ff 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Language/ObjC/NSArray.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Language/ObjC/NSArray.cpp @@ -280,6 +280,22 @@ namespace Foundation1436 { } } +namespace ConstantArray { + +struct ConstantArray32 { + uint64_t used; + uint32_t list; +}; + +struct ConstantArray64 { + uint64_t used; + uint64_t list; +}; + +using NSConstantArraySyntheticFrontEnd = + GenericNSArrayISyntheticFrontEnd<ConstantArray32, ConstantArray64, false>; +} // namespace ConstantArray + class NSArray0SyntheticFrontEnd : public SyntheticChildrenFrontEnd { public: NSArray0SyntheticFrontEnd(lldb::ValueObjectSP valobj_sp); @@ -356,6 +372,7 @@ bool lldb_private::formatters::NSArraySummaryProvider( static const ConstString g_NSArrayMLegacy("__NSArrayM_Legacy"); static const ConstString g_NSArrayMImmutable("__NSArrayM_Immutable"); static const ConstString g_NSCallStackArray("_NSCallStackArray"); + static const ConstString g_NSConstantArray("NSConstantArray"); if (class_name.IsEmpty()) return false; @@ -366,6 +383,12 @@ bool lldb_private::formatters::NSArraySummaryProvider( ptr_size, 0, error); if (error.Fail()) return false; + } else if (class_name == g_NSConstantArray) { + Status error; + value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + ptr_size, 8, + 0, error); + if (error.Fail()) + return false; } else if (class_name == g_NSArrayM) { AppleObjCRuntime *apple_runtime = llvm::dyn_cast_or_null<AppleObjCRuntime>(runtime); @@ -803,6 +826,7 @@ lldb_private::formatters::NSArraySyntheticFrontEndCreator( ConstString class_name(descriptor->GetClassName()); static const ConstString g_NSArrayI("__NSArrayI"); + static const ConstString g_NSConstantArray("NSConstantArray"); static const ConstString g_NSArrayI_Transfer("__NSArrayI_Transfer"); static const ConstString g_NSFrozenArrayM("__NSFrozenArrayM"); static const ConstString g_NSArrayM("__NSArrayM"); @@ -823,6 +847,8 @@ lldb_private::formatters::NSArraySyntheticFrontEndCreator( return (new Foundation1300::NSArrayISyntheticFrontEnd(valobj_sp)); } else if (class_name == g_NSArrayI_Transfer) { return (new Foundation1436::NSArrayI_TransferSyntheticFrontEnd(valobj_sp)); + } else if (class_name == g_NSConstantArray) { + return new ConstantArray::NSConstantArraySyntheticFrontEnd(valobj_sp); } else if (class_name == g_NSFrozenArrayM) { return (new Foundation1436::NSFrozenArrayMSyntheticFrontEnd(valobj_sp)); } else if (class_name == g_NSArray0) { diff --git a/contrib/llvm-project/lldb/source/Plugins/Language/ObjC/NSDictionary.cpp b/contrib/llvm-project/lldb/source/Plugins/Language/ObjC/NSDictionary.cpp index 326f47a10660..73c40ba959a6 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Language/ObjC/NSDictionary.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Language/ObjC/NSDictionary.cpp @@ -142,6 +142,38 @@ private: std::vector<DictionaryItemDescriptor> m_children; }; +class NSConstantDictionarySyntheticFrontEnd : public SyntheticChildrenFrontEnd { +public: + NSConstantDictionarySyntheticFrontEnd(lldb::ValueObjectSP valobj_sp); + + size_t CalculateNumChildren() override; + + lldb::ValueObjectSP GetChildAtIndex(size_t idx) override; + + bool Update() override; + + bool MightHaveChildren() override; + + size_t GetIndexOfChildWithName(ConstString name) override; + +private: + ExecutionContextRef m_exe_ctx_ref; + CompilerType m_pair_type; + uint8_t m_ptr_size = 8; + lldb::ByteOrder m_order = lldb::eByteOrderInvalid; + unsigned int m_size = 0; + lldb::addr_t m_keys_ptr = LLDB_INVALID_ADDRESS; + lldb::addr_t m_objects_ptr = LLDB_INVALID_ADDRESS; + + struct DictionaryItemDescriptor { + lldb::addr_t key_ptr; + lldb::addr_t val_ptr; + lldb::ValueObjectSP valobj_sp; + }; + + std::vector<DictionaryItemDescriptor> m_children; +}; + class NSCFDictionarySyntheticFrontEnd : public SyntheticChildrenFrontEnd { public: NSCFDictionarySyntheticFrontEnd(lldb::ValueObjectSP valobj_sp); @@ -302,7 +334,6 @@ namespace Foundation1428 { } namespace Foundation1437 { - namespace { static const uint64_t NSDictionaryCapacities[] = { 0, 3, 7, 13, 23, 41, 71, 127, 191, 251, 383, 631, 1087, 1723, 2803, 4523, 7351, 11959, 19447, 31231, 50683, 81919, 132607, @@ -313,7 +344,8 @@ namespace Foundation1437 { static const size_t NSDictionaryNumSizeBuckets = sizeof(NSDictionaryCapacities) / sizeof(uint64_t); - + + namespace { struct DataDescriptor_32 { uint32_t _buffer; uint32_t _muts; @@ -339,8 +371,8 @@ namespace Foundation1437 { 0 : NSDictionaryCapacities[_szidx]; } }; - } - + } // namespace + using NSDictionaryMSyntheticFrontEnd = GenericNSDictionaryMSyntheticFrontEnd<DataDescriptor_32, DataDescriptor_64>; @@ -416,6 +448,7 @@ bool lldb_private::formatters::NSDictionarySummaryProvider( static const ConstString g_DictionaryCF("__CFDictionary"); static const ConstString g_DictionaryNSCF("__NSCFDictionary"); static const ConstString g_DictionaryCFRef("CFDictionaryRef"); + static const ConstString g_ConstantDictionary("NSConstantDictionary"); if (class_name.IsEmpty()) return false; @@ -428,8 +461,14 @@ bool lldb_private::formatters::NSDictionarySummaryProvider( return false; value &= (is_64bit ? ~0xFC00000000000000UL : ~0xFC000000U); - } else if (class_name == g_DictionaryM || class_name == g_DictionaryMLegacy - || class_name == g_DictionaryMFrozen) { + } else if (class_name == g_ConstantDictionary) { + Status error; + value = process_sp->ReadUnsignedIntegerFromMemory( + valobj_addr + 2 * ptr_size, ptr_size, 0, error); + if (error.Fail()) + return false; + } else if (class_name == g_DictionaryM || class_name == g_DictionaryMLegacy || + class_name == g_DictionaryMFrozen) { AppleObjCRuntime *apple_runtime = llvm::dyn_cast_or_null<AppleObjCRuntime>(runtime); Status error; @@ -447,8 +486,7 @@ bool lldb_private::formatters::NSDictionarySummaryProvider( value = 1; } else if (class_name == g_Dictionary0) { value = 0; - } else if (class_name == g_DictionaryCF || - class_name == g_DictionaryNSCF || + } else if (class_name == g_DictionaryCF || class_name == g_DictionaryNSCF || class_name == g_DictionaryCFRef) { ExecutionContext exe_ctx(process_sp); CFBasicHash cfbh; @@ -517,12 +555,15 @@ lldb_private::formatters::NSDictionarySyntheticFrontEndCreator( static const ConstString g_DictionaryCF("__CFDictionary"); static const ConstString g_DictionaryNSCF("__NSCFDictionary"); static const ConstString g_DictionaryCFRef("CFDictionaryRef"); + static const ConstString g_ConstantDictionary("NSConstantDictionary"); if (class_name.IsEmpty()) return nullptr; if (class_name == g_DictionaryI) { return (new NSDictionaryISyntheticFrontEnd(valobj_sp)); + } else if (class_name == g_ConstantDictionary) { + return (new NSConstantDictionarySyntheticFrontEnd(valobj_sp)); } else if (class_name == g_DictionaryM || class_name == g_DictionaryMFrozen) { if (runtime->GetFoundationVersion() >= 1437) { return (new Foundation1437::NSDictionaryMSyntheticFrontEnd(valobj_sp)); @@ -532,11 +573,10 @@ lldb_private::formatters::NSDictionarySyntheticFrontEndCreator( return (new Foundation1100::NSDictionaryMSyntheticFrontEnd(valobj_sp)); } } else if (class_name == g_DictionaryMLegacy) { - return (new Foundation1100::NSDictionaryMSyntheticFrontEnd(valobj_sp)); + return (new Foundation1100::NSDictionaryMSyntheticFrontEnd(valobj_sp)); } else if (class_name == g_Dictionary1) { return (new NSDictionary1SyntheticFrontEnd(valobj_sp)); - } else if (class_name == g_DictionaryCF || - class_name == g_DictionaryNSCF || + } else if (class_name == g_DictionaryCF || class_name == g_DictionaryNSCF || class_name == g_DictionaryCFRef) { return (new NSCFDictionarySyntheticFrontEnd(valobj_sp)); } else { @@ -830,6 +870,120 @@ lldb_private::formatters::NSCFDictionarySyntheticFrontEnd::GetChildAtIndex( return dict_item.valobj_sp; } +lldb_private::formatters::NSConstantDictionarySyntheticFrontEnd:: + NSConstantDictionarySyntheticFrontEnd(lldb::ValueObjectSP valobj_sp) + : SyntheticChildrenFrontEnd(*valobj_sp) {} + +size_t lldb_private::formatters::NSConstantDictionarySyntheticFrontEnd:: + GetIndexOfChildWithName(ConstString name) { + const char *item_name = name.GetCString(); + uint32_t idx = ExtractIndexFromString(item_name); + if (idx < UINT32_MAX && idx >= CalculateNumChildren()) + return UINT32_MAX; + return idx; +} + +size_t lldb_private::formatters::NSConstantDictionarySyntheticFrontEnd:: + CalculateNumChildren() { + return m_size; +} + +bool lldb_private::formatters::NSConstantDictionarySyntheticFrontEnd::Update() { + ValueObjectSP valobj_sp = m_backend.GetSP(); + if (!valobj_sp) + return false; + m_exe_ctx_ref = valobj_sp->GetExecutionContextRef(); + Status error; + error.Clear(); + lldb::ProcessSP process_sp(valobj_sp->GetProcessSP()); + if (!process_sp) + return false; + m_ptr_size = process_sp->GetAddressByteSize(); + m_order = process_sp->GetByteOrder(); + uint64_t valobj_addr = valobj_sp->GetValueAsUnsigned(0); + m_size = process_sp->ReadUnsignedIntegerFromMemory( + valobj_addr + 2 * m_ptr_size, m_ptr_size, 0, error); + if (error.Fail()) + return false; + m_keys_ptr = + process_sp->ReadPointerFromMemory(valobj_addr + 3 * m_ptr_size, error); + if (error.Fail()) + return false; + m_objects_ptr = + process_sp->ReadPointerFromMemory(valobj_addr + 4 * m_ptr_size, error); + return !error.Fail(); +} + +bool lldb_private::formatters::NSConstantDictionarySyntheticFrontEnd:: + MightHaveChildren() { + return true; +} + +lldb::ValueObjectSP lldb_private::formatters:: + NSConstantDictionarySyntheticFrontEnd::GetChildAtIndex(size_t idx) { + uint32_t num_children = CalculateNumChildren(); + + if (idx >= num_children) + return lldb::ValueObjectSP(); + + if (m_children.empty()) { + // do the scan phase + lldb::addr_t key_at_idx = 0, val_at_idx = 0; + ProcessSP process_sp = m_exe_ctx_ref.GetProcessSP(); + if (!process_sp) + return lldb::ValueObjectSP(); + + for (unsigned int child = 0; child < num_children; ++child) { + Status error; + key_at_idx = process_sp->ReadPointerFromMemory( + m_keys_ptr + child * m_ptr_size, error); + if (error.Fail()) + return lldb::ValueObjectSP(); + val_at_idx = process_sp->ReadPointerFromMemory( + m_objects_ptr + child * m_ptr_size, error); + if (error.Fail()) + return lldb::ValueObjectSP(); + DictionaryItemDescriptor descriptor = {key_at_idx, val_at_idx, + lldb::ValueObjectSP()}; + m_children.push_back(descriptor); + } + } + + if (idx >= m_children.size()) // should never happen + return lldb::ValueObjectSP(); + + DictionaryItemDescriptor &dict_item = m_children[idx]; + if (!dict_item.valobj_sp) { + if (!m_pair_type.IsValid()) { + TargetSP target_sp(m_backend.GetTargetSP()); + if (!target_sp) + return ValueObjectSP(); + m_pair_type = GetLLDBNSPairType(target_sp); + } + if (!m_pair_type.IsValid()) + return ValueObjectSP(); + + DataBufferSP buffer_sp(new DataBufferHeap(2 * m_ptr_size, 0)); + + if (m_ptr_size == 8) { + uint64_t *data_ptr = (uint64_t *)buffer_sp->GetBytes(); + *data_ptr = dict_item.key_ptr; + *(data_ptr + 1) = dict_item.val_ptr; + } else { + uint32_t *data_ptr = (uint32_t *)buffer_sp->GetBytes(); + *data_ptr = dict_item.key_ptr; + *(data_ptr + 1) = dict_item.val_ptr; + } + + StreamString idx_name; + idx_name.Printf("[%" PRIu64 "]", (uint64_t)idx); + DataExtractor data(buffer_sp, m_order, m_ptr_size); + dict_item.valobj_sp = CreateValueObjectFromData(idx_name.GetString(), data, + m_exe_ctx_ref, m_pair_type); + } + return dict_item.valobj_sp; +} + lldb_private::formatters::NSDictionary1SyntheticFrontEnd:: NSDictionary1SyntheticFrontEnd(lldb::ValueObjectSP valobj_sp) : SyntheticChildrenFrontEnd(*valobj_sp.get()), m_pair(nullptr) {} diff --git a/contrib/llvm-project/lldb/source/Plugins/Language/ObjC/NSString.cpp b/contrib/llvm-project/lldb/source/Plugins/Language/ObjC/NSString.cpp index 85922992eb2b..2b5161e781f2 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Language/ObjC/NSString.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Language/ObjC/NSString.cpp @@ -166,7 +166,7 @@ bool lldb_private::formatters::NSStringSummaryProvider( return false; if (has_explicit_length && is_unicode) { options.SetLocation(location); - options.SetProcessSP(process_sp); + options.SetTargetSP(valobj.GetTargetSP()); options.SetStream(&stream); options.SetQuote('"'); options.SetSourceSize(explicit_length); @@ -179,7 +179,7 @@ bool lldb_private::formatters::NSStringSummaryProvider( StringPrinter::StringElementType::UTF16>(options); } else { options.SetLocation(location + 1); - options.SetProcessSP(process_sp); + options.SetTargetSP(valobj.GetTargetSP()); options.SetStream(&stream); options.SetSourceSize(explicit_length); options.SetHasSourceSize(has_explicit_length); @@ -195,7 +195,7 @@ bool lldb_private::formatters::NSStringSummaryProvider( uint64_t location = 3 * ptr_size + valobj_addr; options.SetLocation(location); - options.SetProcessSP(process_sp); + options.SetTargetSP(valobj.GetTargetSP()); options.SetStream(&stream); options.SetQuote('"'); options.SetSourceSize(explicit_length); @@ -217,7 +217,7 @@ bool lldb_private::formatters::NSStringSummaryProvider( return false; } options.SetLocation(location); - options.SetProcessSP(process_sp); + options.SetTargetSP(valobj.GetTargetSP()); options.SetStream(&stream); options.SetQuote('"'); options.SetSourceSize(explicit_length); @@ -237,7 +237,7 @@ bool lldb_private::formatters::NSStringSummaryProvider( lldb::addr_t location = valobj.GetValueAsUnsigned(0) + ptr_size + 4; options.SetLocation(location); - options.SetProcessSP(process_sp); + options.SetTargetSP(valobj.GetTargetSP()); options.SetStream(&stream); options.SetQuote('"'); options.SetSourceSize(explicit_length); @@ -260,7 +260,7 @@ bool lldb_private::formatters::NSStringSummaryProvider( location++; } options.SetLocation(location); - options.SetProcessSP(process_sp); + options.SetTargetSP(valobj.GetTargetSP()); options.SetStream(&stream); options.SetSourceSize(explicit_length); options.SetHasSourceSize(has_explicit_length); @@ -283,7 +283,7 @@ bool lldb_private::formatters::NSStringSummaryProvider( explicit_length++; // account for the fact that there is no NULL and we // need to have one added options.SetLocation(location); - options.SetProcessSP(process_sp); + options.SetTargetSP(valobj.GetTargetSP()); options.SetStream(&stream); options.SetSourceSize(explicit_length); options.SetHasSourceSize(has_explicit_length); diff --git a/contrib/llvm-project/lldb/source/Plugins/Language/ObjC/ObjCConstants.h b/contrib/llvm-project/lldb/source/Plugins/Language/ObjC/ObjCConstants.h new file mode 100644 index 000000000000..c7c498d4cab3 --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Language/ObjC/ObjCConstants.h @@ -0,0 +1,44 @@ +//===-- ObjCConstants.h------------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_SOURCE_PLUGINS_LANGUAGE_OBJC_OBJCCONSTANTS_H +#define LLDB_SOURCE_PLUGINS_LANGUAGE_OBJC_OBJCCONSTANTS_H + +// Objective-C Type Encoding +#define _C_ID '@' +#define _C_CLASS '#' +#define _C_SEL ':' +#define _C_CHR 'c' +#define _C_UCHR 'C' +#define _C_SHT 's' +#define _C_USHT 'S' +#define _C_INT 'i' +#define _C_UINT 'I' +#define _C_LNG 'l' +#define _C_ULNG 'L' +#define _C_LNG_LNG 'q' +#define _C_ULNG_LNG 'Q' +#define _C_FLT 'f' +#define _C_DBL 'd' +#define _C_BFLD 'b' +#define _C_BOOL 'B' +#define _C_VOID 'v' +#define _C_UNDEF '?' +#define _C_PTR '^' +#define _C_CHARPTR '*' +#define _C_ATOM '%' +#define _C_ARY_B '[' +#define _C_ARY_E ']' +#define _C_UNION_B '(' +#define _C_UNION_E ')' +#define _C_STRUCT_B '{' +#define _C_STRUCT_E '}' +#define _C_VECTOR '!' +#define _C_CONST 'r' + +#endif // LLDB_SOURCE_PLUGINS_LANGUAGE_OBJC_OBJCCONSTANTS_H diff --git a/contrib/llvm-project/lldb/source/Plugins/Language/ObjC/ObjCLanguage.cpp b/contrib/llvm-project/lldb/source/Plugins/Language/ObjC/ObjCLanguage.cpp index 379c53432b7b..99ce389bb53e 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Language/ObjC/ObjCLanguage.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Language/ObjC/ObjCLanguage.cpp @@ -48,19 +48,6 @@ void ObjCLanguage::Terminate() { PluginManager::UnregisterPlugin(CreateInstance); } -lldb_private::ConstString ObjCLanguage::GetPluginNameStatic() { - static ConstString g_name("objc"); - return g_name; -} - -// PluginInterface protocol - -lldb_private::ConstString ObjCLanguage::GetPluginName() { - return GetPluginNameStatic(); -} - -uint32_t ObjCLanguage::GetPluginVersion() { return 1; } - // Static Functions Language *ObjCLanguage::CreateInstance(lldb::LanguageType language) { @@ -405,6 +392,9 @@ static void LoadObjCFormatters(TypeCategoryImplSP objc_category_sp) { "NSArray summary provider", ConstString("NSArray"), appkit_flags); AddCXXSummary( objc_category_sp, lldb_private::formatters::NSArraySummaryProvider, + "NSArray summary provider", ConstString("NSConstantArray"), appkit_flags); + AddCXXSummary( + objc_category_sp, lldb_private::formatters::NSArraySummaryProvider, "NSArray summary provider", ConstString("NSMutableArray"), appkit_flags); AddCXXSummary( objc_category_sp, lldb_private::formatters::NSArraySummaryProvider, @@ -440,6 +430,10 @@ static void LoadObjCFormatters(TypeCategoryImplSP objc_category_sp) { AddCXXSummary(objc_category_sp, lldb_private::formatters::NSDictionarySummaryProvider<false>, "NSDictionary summary provider", + ConstString("NSConstantDictionary"), appkit_flags); + AddCXXSummary(objc_category_sp, + lldb_private::formatters::NSDictionarySummaryProvider<false>, + "NSDictionary summary provider", ConstString("NSMutableDictionary"), appkit_flags); AddCXXSummary(objc_category_sp, lldb_private::formatters::NSDictionarySummaryProvider<false>, @@ -545,6 +539,10 @@ static void LoadObjCFormatters(TypeCategoryImplSP objc_category_sp) { ScriptedSyntheticChildren::Flags()); AddCXXSynthetic(objc_category_sp, lldb_private::formatters::NSArraySyntheticFrontEndCreator, + "NSArray synthetic children", ConstString("NSConstantArray"), + ScriptedSyntheticChildren::Flags()); + AddCXXSynthetic(objc_category_sp, + lldb_private::formatters::NSArraySyntheticFrontEndCreator, "NSArray synthetic children", ConstString("NSMutableArray"), ScriptedSyntheticChildren::Flags()); AddCXXSynthetic(objc_category_sp, @@ -573,6 +571,11 @@ static void LoadObjCFormatters(TypeCategoryImplSP objc_category_sp) { AddCXXSynthetic( objc_category_sp, lldb_private::formatters::NSDictionarySyntheticFrontEndCreator, + "NSDictionary synthetic children", ConstString("NSConstantDictionary"), + ScriptedSyntheticChildren::Flags()); + AddCXXSynthetic( + objc_category_sp, + lldb_private::formatters::NSDictionarySyntheticFrontEndCreator, "NSDictionary synthetic children", ConstString("__NSDictionaryI"), ScriptedSyntheticChildren::Flags()); AddCXXSynthetic( @@ -791,6 +794,18 @@ static void LoadObjCFormatters(TypeCategoryImplSP objc_category_sp) { AddCXXSummary( objc_category_sp, lldb_private::formatters::NSNumberSummaryProvider, "NSNumber summary provider", ConstString("NSNumber"), appkit_flags); + AddCXXSummary(objc_category_sp, + lldb_private::formatters::NSNumberSummaryProvider, + "NSNumber summary provider", + ConstString("NSConstantIntegerNumber"), appkit_flags); + AddCXXSummary(objc_category_sp, + lldb_private::formatters::NSNumberSummaryProvider, + "NSNumber summary provider", + ConstString("NSConstantDoubleNumber"), appkit_flags); + AddCXXSummary(objc_category_sp, + lldb_private::formatters::NSNumberSummaryProvider, + "NSNumber summary provider", + ConstString("NSConstantFloatNumber"), appkit_flags); AddCXXSummary( objc_category_sp, lldb_private::formatters::NSNumberSummaryProvider, "CFNumberRef summary provider", ConstString("CFNumberRef"), appkit_flags); @@ -906,7 +921,8 @@ lldb::TypeCategoryImplSP ObjCLanguage::GetFormatters() { static TypeCategoryImplSP g_category; llvm::call_once(g_initialize, [this]() -> void { - DataVisualization::Categories::GetCategory(GetPluginName(), g_category); + DataVisualization::Categories::GetCategory(ConstString(GetPluginName()), + g_category); if (g_category) { LoadCoreMediaFormatters(g_category); LoadObjCFormatters(g_category); diff --git a/contrib/llvm-project/lldb/source/Plugins/Language/ObjC/ObjCLanguage.h b/contrib/llvm-project/lldb/source/Plugins/Language/ObjC/ObjCLanguage.h index 691c51883c8a..914452086db7 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Language/ObjC/ObjCLanguage.h +++ b/contrib/llvm-project/lldb/source/Plugins/Language/ObjC/ObjCLanguage.h @@ -133,7 +133,7 @@ public: static lldb_private::Language *CreateInstance(lldb::LanguageType language); - static lldb_private::ConstString GetPluginNameStatic(); + static llvm::StringRef GetPluginNameStatic() { return "objc"; } static bool IsPossibleObjCMethodName(const char *name) { if (!name) @@ -156,9 +156,7 @@ public: } // PluginInterface protocol - ConstString GetPluginName() override; - - uint32_t GetPluginVersion() override; + llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); } }; } // namespace lldb_private diff --git a/contrib/llvm-project/lldb/source/Plugins/Language/ObjCPlusPlus/ObjCPlusPlusLanguage.cpp b/contrib/llvm-project/lldb/source/Plugins/Language/ObjCPlusPlus/ObjCPlusPlusLanguage.cpp index 359978553210..700dda3d33bb 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Language/ObjCPlusPlus/ObjCPlusPlusLanguage.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Language/ObjCPlusPlus/ObjCPlusPlusLanguage.cpp @@ -34,18 +34,6 @@ void ObjCPlusPlusLanguage::Terminate() { PluginManager::UnregisterPlugin(CreateInstance); } -lldb_private::ConstString ObjCPlusPlusLanguage::GetPluginNameStatic() { - static ConstString g_name("objcplusplus"); - return g_name; -} - -// PluginInterface protocol -lldb_private::ConstString ObjCPlusPlusLanguage::GetPluginName() { - return GetPluginNameStatic(); -} - -uint32_t ObjCPlusPlusLanguage::GetPluginVersion() { return 1; } - // Static Functions Language *ObjCPlusPlusLanguage::CreateInstance(lldb::LanguageType language) { switch (language) { diff --git a/contrib/llvm-project/lldb/source/Plugins/Language/ObjCPlusPlus/ObjCPlusPlusLanguage.h b/contrib/llvm-project/lldb/source/Plugins/Language/ObjCPlusPlus/ObjCPlusPlusLanguage.h index 233fd5c00a7a..20184fd709d5 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Language/ObjCPlusPlus/ObjCPlusPlusLanguage.h +++ b/contrib/llvm-project/lldb/source/Plugins/Language/ObjCPlusPlus/ObjCPlusPlusLanguage.h @@ -40,12 +40,10 @@ public: static lldb_private::Language *CreateInstance(lldb::LanguageType language); - static lldb_private::ConstString GetPluginNameStatic(); + static llvm::StringRef GetPluginNameStatic() { return "objcplusplus"; } // PluginInterface protocol - ConstString GetPluginName() override; - - uint32_t GetPluginVersion() override; + llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); } }; } // namespace lldb_private diff --git a/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp b/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp index f5b587c51960..92f732fe6827 100644 --- a/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp @@ -405,18 +405,6 @@ void ItaniumABILanguageRuntime::Terminate() { PluginManager::UnregisterPlugin(CreateInstance); } -lldb_private::ConstString ItaniumABILanguageRuntime::GetPluginNameStatic() { - static ConstString g_name("itanium"); - return g_name; -} - -// PluginInterface protocol -lldb_private::ConstString ItaniumABILanguageRuntime::GetPluginName() { - return GetPluginNameStatic(); -} - -uint32_t ItaniumABILanguageRuntime::GetPluginVersion() { return 1; } - BreakpointResolverSP ItaniumABILanguageRuntime::CreateExceptionResolver( const BreakpointSP &bkpt, bool catch_bp, bool throw_bp) { return CreateExceptionResolver(bkpt, catch_bp, throw_bp, false); diff --git a/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.h b/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.h index d591527d9257..ca8d5ab1a93a 100644 --- a/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.h +++ b/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.h @@ -35,7 +35,7 @@ public: static lldb_private::LanguageRuntime * CreateInstance(Process *process, lldb::LanguageType language); - static lldb_private::ConstString GetPluginNameStatic(); + static llvm::StringRef GetPluginNameStatic() { return "itanium"; } static char ID; @@ -76,9 +76,7 @@ public: lldb::ThreadSP thread_sp) override; // PluginInterface protocol - lldb_private::ConstString GetPluginName() override; - - uint32_t GetPluginVersion() override; + llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); } protected: lldb::BreakpointResolverSP diff --git a/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.cpp b/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.cpp index 405b8a6f16b7..162ccad3cdcd 100644 --- a/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.cpp @@ -9,6 +9,7 @@ #include "AppleObjCClassDescriptorV2.h" #include "lldb/Expression/FunctionCaller.h" +#include "lldb/Target/ABI.h" #include "lldb/Utility/Log.h" using namespace lldb; @@ -73,6 +74,10 @@ bool ClassDescriptorV2::objc_class_t::Read(Process *process, m_flags = (uint8_t)(data_NEVER_USE & (lldb::addr_t)3); m_data_ptr = data_NEVER_USE & GetClassDataMask(process); + if (ABISP abi_sp = process->GetABI()) { + m_isa = abi_sp->FixCodeAddress(m_isa); + m_superclass = abi_sp->FixCodeAddress(m_superclass); + } return true; } @@ -105,6 +110,8 @@ bool ClassDescriptorV2::class_rw_t::Read(Process *process, lldb::addr_t addr) { m_flags = extractor.GetU32_unchecked(&cursor); m_version = extractor.GetU32_unchecked(&cursor); m_ro_ptr = extractor.GetAddress_unchecked(&cursor); + if (ABISP abi_sp = process->GetABI()) + m_ro_ptr = abi_sp->FixCodeAddress(m_ro_ptr); m_method_list_ptr = extractor.GetAddress_unchecked(&cursor); m_properties_ptr = extractor.GetAddress_unchecked(&cursor); m_firstSubclass = extractor.GetAddress_unchecked(&cursor); @@ -120,6 +127,8 @@ bool ClassDescriptorV2::class_rw_t::Read(Process *process, lldb::addr_t addr) { process->GetByteOrder(), process->GetAddressByteSize()); m_ro_ptr = extractor.GetAddress_unchecked(&cursor); + if (ABISP abi_sp = process->GetABI()) + m_ro_ptr = abi_sp->FixCodeAddress(m_ro_ptr); } return true; @@ -231,6 +240,8 @@ bool ClassDescriptorV2::method_list_t::Read(Process *process, DataBufferHeap buffer(size, '\0'); Status error; + if (ABISP abi_sp = process->GetABI()) + addr = abi_sp->FixCodeAddress(addr); process->ReadMemory(addr, buffer.GetBytes(), size, error); if (error.Fail()) { return false; diff --git a/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp b/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp index 98d0e9cf991b..609e8e9bc1b6 100644 --- a/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp @@ -92,18 +92,6 @@ void AppleObjCRuntimeV1::Terminate() { PluginManager::UnregisterPlugin(CreateInstance); } -lldb_private::ConstString AppleObjCRuntimeV1::GetPluginNameStatic() { - static ConstString g_name("apple-objc-v1"); - return g_name; -} - -// PluginInterface protocol -ConstString AppleObjCRuntimeV1::GetPluginName() { - return GetPluginNameStatic(); -} - -uint32_t AppleObjCRuntimeV1::GetPluginVersion() { return 1; } - BreakpointResolverSP AppleObjCRuntimeV1::CreateExceptionResolver(const BreakpointSP &bkpt, bool catch_bp, bool throw_bp) { diff --git a/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.h b/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.h index 12ee2cc53639..46d8e89c906e 100644 --- a/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.h +++ b/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.h @@ -28,7 +28,7 @@ public: static lldb_private::LanguageRuntime * CreateInstance(Process *process, lldb::LanguageType language); - static lldb_private::ConstString GetPluginNameStatic(); + static llvm::StringRef GetPluginNameStatic() { return "apple-objc-v1"; } static char ID; @@ -107,9 +107,7 @@ public: CreateObjectChecker(std::string, ExecutionContext &exe_ctx) override; // PluginInterface protocol - ConstString GetPluginName() override; - - uint32_t GetPluginVersion() override; + llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); } ObjCRuntimeVersions GetRuntimeVersion() const override { return ObjCRuntimeVersions::eAppleObjC_V1; diff --git a/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp b/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp index 10512a97ad69..bd6b6335ca8c 100644 --- a/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp @@ -292,6 +292,7 @@ struct objc_clsopt_v16_t { uint32_t occupied; uint32_t shift; uint32_t mask; + uint32_t zero; uint64_t salt; uint32_t scramble[256]; uint8_t tab[0]; // tab[mask+1] @@ -950,50 +951,70 @@ protected: Process *process = m_exe_ctx.GetProcessPtr(); ExecutionContext exe_ctx(process); + ObjCLanguageRuntime *objc_runtime = ObjCLanguageRuntime::Get(*process); - if (objc_runtime) { - ObjCLanguageRuntime::TaggedPointerVendor *tagged_ptr_vendor = - objc_runtime->GetTaggedPointerVendor(); - if (tagged_ptr_vendor) { - for (size_t i = 0; i < command.GetArgumentCount(); i++) { - const char *arg_str = command.GetArgumentAtIndex(i); - if (!arg_str) - continue; - Status error; - lldb::addr_t arg_addr = OptionArgParser::ToAddress( - &exe_ctx, arg_str, LLDB_INVALID_ADDRESS, &error); - if (arg_addr == 0 || arg_addr == LLDB_INVALID_ADDRESS || error.Fail()) - continue; - auto descriptor_sp = tagged_ptr_vendor->GetClassDescriptor(arg_addr); - if (!descriptor_sp) - continue; - uint64_t info_bits = 0; - uint64_t value_bits = 0; - uint64_t payload = 0; - if (descriptor_sp->GetTaggedPointerInfo(&info_bits, &value_bits, - &payload)) { - result.GetOutputStream().Printf( - "0x%" PRIx64 " is tagged.\n\tpayload = 0x%" PRIx64 - "\n\tvalue = 0x%" PRIx64 "\n\tinfo bits = 0x%" PRIx64 - "\n\tclass = %s\n", - (uint64_t)arg_addr, payload, value_bits, info_bits, - descriptor_sp->GetClassName().AsCString("<unknown>")); - } else { - result.GetOutputStream().Printf("0x%" PRIx64 " is not tagged.\n", - (uint64_t)arg_addr); - } - } - } else { - result.AppendError("current process has no tagged pointer support"); + if (!objc_runtime) { + result.AppendError("current process has no Objective-C runtime loaded"); + result.SetStatus(lldb::eReturnStatusFailed); + return false; + } + + ObjCLanguageRuntime::TaggedPointerVendor *tagged_ptr_vendor = + objc_runtime->GetTaggedPointerVendor(); + if (!tagged_ptr_vendor) { + result.AppendError("current process has no tagged pointer support"); + result.SetStatus(lldb::eReturnStatusFailed); + return false; + } + + for (size_t i = 0; i < command.GetArgumentCount(); i++) { + const char *arg_str = command.GetArgumentAtIndex(i); + if (!arg_str) + continue; + + Status error; + lldb::addr_t arg_addr = OptionArgParser::ToAddress( + &exe_ctx, arg_str, LLDB_INVALID_ADDRESS, &error); + if (arg_addr == 0 || arg_addr == LLDB_INVALID_ADDRESS || error.Fail()) { + result.AppendErrorWithFormatv( + "could not convert '{0}' to a valid address\n", arg_str); result.SetStatus(lldb::eReturnStatusFailed); return false; } - result.SetStatus(lldb::eReturnStatusSuccessFinishResult); - return true; + + if (!tagged_ptr_vendor->IsPossibleTaggedPointer(arg_addr)) { + result.GetOutputStream().Format("{0:x16} is not tagged\n", arg_addr); + continue; + } + + auto descriptor_sp = tagged_ptr_vendor->GetClassDescriptor(arg_addr); + if (!descriptor_sp) { + result.AppendErrorWithFormatv( + "could not get class descriptor for {0:x16}\n", arg_addr); + result.SetStatus(lldb::eReturnStatusFailed); + return false; + } + + uint64_t info_bits = 0; + uint64_t value_bits = 0; + uint64_t payload = 0; + if (descriptor_sp->GetTaggedPointerInfo(&info_bits, &value_bits, + &payload)) { + result.GetOutputStream().Format( + "{0:x} is tagged\n" + "\tpayload = {1:x16}\n" + "\tvalue = {2:x16}\n" + "\tinfo bits = {3:x16}\n" + "\tclass = {4}\n", + arg_addr, payload, value_bits, info_bits, + descriptor_sp->GetClassName().AsCString("<unknown>")); + } else { + result.GetOutputStream().Format("{0:x16} is not tagged\n", arg_addr); + } } - result.AppendError("current process has no Objective-C runtime loaded"); - result.SetStatus(lldb::eReturnStatusFailed); - return false; + + result.SetStatus(lldb::eReturnStatusSuccessFinishResult); + return true; } }; @@ -1060,18 +1081,6 @@ void AppleObjCRuntimeV2::Terminate() { PluginManager::UnregisterPlugin(CreateInstance); } -lldb_private::ConstString AppleObjCRuntimeV2::GetPluginNameStatic() { - static ConstString g_name("apple-objc-v2"); - return g_name; -} - -// PluginInterface protocol -lldb_private::ConstString AppleObjCRuntimeV2::GetPluginName() { - return GetPluginNameStatic(); -} - -uint32_t AppleObjCRuntimeV2::GetPluginVersion() { return 1; } - BreakpointResolverSP AppleObjCRuntimeV2::CreateExceptionResolver(const BreakpointSP &bkpt, bool catch_bp, bool throw_bp) { @@ -2001,6 +2010,11 @@ AppleObjCRuntimeV2::SharedCacheClassInfoExtractor::UpdateISAToDescriptorMap() { const uint32_t num_classes = 128 * 1024; UtilityFunction *get_class_info_code = GetClassInfoUtilityFunction(exe_ctx); + if (!get_class_info_code) { + // The callee will have already logged a useful error message. + return DescriptorMapUpdateResult::Fail(); + } + FunctionCaller *get_shared_cache_class_info_function = get_class_info_code->GetFunctionCaller(); @@ -2188,8 +2202,12 @@ lldb::addr_t AppleObjCRuntimeV2::GetSharedCacheBaseAddress() { if (!info_dict) return LLDB_INVALID_ADDRESS; - return info_dict->GetValueForKey("shared_cache_base_address") - ->GetIntegerValue(LLDB_INVALID_ADDRESS); + StructuredData::ObjectSP value = + info_dict->GetValueForKey("shared_cache_base_address"); + if (!value) + return LLDB_INVALID_ADDRESS; + + return value->GetIntegerValue(LLDB_INVALID_ADDRESS); } void AppleObjCRuntimeV2::UpdateISAToDescriptorMapIfNeeded() { @@ -2299,13 +2317,9 @@ static bool DoesProcessHaveSharedCache(Process &process) { if (!platform_sp) return true; // this should not happen - ConstString platform_plugin_name = platform_sp->GetPluginName(); - if (platform_plugin_name) { - llvm::StringRef platform_plugin_name_sr = - platform_plugin_name.GetStringRef(); - if (platform_plugin_name_sr.endswith("-simulator")) - return false; - } + llvm::StringRef platform_plugin_name_sr = platform_sp->GetPluginName(); + if (platform_plugin_name_sr.endswith("-simulator")) + return false; return true; } @@ -2967,11 +2981,13 @@ bool AppleObjCRuntimeV2::GetCFBooleanValuesIfNeeded() { if (m_CFBoolean_values) return true; - static ConstString g_kCFBooleanFalse("__kCFBooleanFalse"); - static ConstString g_kCFBooleanTrue("__kCFBooleanTrue"); + static ConstString g___kCFBooleanFalse("__kCFBooleanFalse"); + static ConstString g___kCFBooleanTrue("__kCFBooleanTrue"); + static ConstString g_kCFBooleanFalse("kCFBooleanFalse"); + static ConstString g_kCFBooleanTrue("kCFBooleanTrue"); - std::function<lldb::addr_t(ConstString)> get_symbol = - [this](ConstString sym) -> lldb::addr_t { + std::function<lldb::addr_t(ConstString, ConstString)> get_symbol = + [this](ConstString sym, ConstString real_sym) -> lldb::addr_t { SymbolContextList sc_list; GetProcess()->GetTarget().GetImages().FindSymbolsWithNameAndType( sym, lldb::eSymbolTypeData, sc_list); @@ -2981,12 +2997,26 @@ bool AppleObjCRuntimeV2::GetCFBooleanValuesIfNeeded() { if (sc.symbol) return sc.symbol->GetLoadAddress(&GetProcess()->GetTarget()); } + GetProcess()->GetTarget().GetImages().FindSymbolsWithNameAndType( + real_sym, lldb::eSymbolTypeData, sc_list); + if (sc_list.GetSize() != 1) + return LLDB_INVALID_ADDRESS; - return LLDB_INVALID_ADDRESS; + SymbolContext sc; + sc_list.GetContextAtIndex(0, sc); + if (!sc.symbol) + return LLDB_INVALID_ADDRESS; + + lldb::addr_t addr = sc.symbol->GetLoadAddress(&GetProcess()->GetTarget()); + Status error; + addr = GetProcess()->ReadPointerFromMemory(addr, error); + if (error.Fail()) + return LLDB_INVALID_ADDRESS; + return addr; }; - lldb::addr_t false_addr = get_symbol(g_kCFBooleanFalse); - lldb::addr_t true_addr = get_symbol(g_kCFBooleanTrue); + lldb::addr_t false_addr = get_symbol(g___kCFBooleanFalse, g_kCFBooleanFalse); + lldb::addr_t true_addr = get_symbol(g___kCFBooleanTrue, g_kCFBooleanTrue); return (m_CFBoolean_values = {false_addr, true_addr}).operator bool(); } diff --git a/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h b/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h index d0caa2969115..6266634e64c5 100644 --- a/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h +++ b/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h @@ -33,7 +33,7 @@ public: static lldb_private::LanguageRuntime * CreateInstance(Process *process, lldb::LanguageType language); - static lldb_private::ConstString GetPluginNameStatic(); + static llvm::StringRef GetPluginNameStatic() { return "apple-objc-v2"; } static char ID; @@ -54,9 +54,7 @@ public: llvm::Expected<std::unique_ptr<UtilityFunction>> CreateObjectChecker(std::string name, ExecutionContext &exe_ctx) override; - ConstString GetPluginName() override; - - uint32_t GetPluginVersion() override; + llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); } ObjCRuntimeVersions GetRuntimeVersion() const override { return ObjCRuntimeVersions::eAppleObjC_V2; diff --git a/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.cpp b/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.cpp index 7b0121503bc4..c6cb2be981a7 100644 --- a/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.cpp @@ -78,13 +78,13 @@ AppleObjCTypeEncodingParser::ReadStructElement(TypeSystemClang &ast_ctx, clang::QualType AppleObjCTypeEncodingParser::BuildStruct( TypeSystemClang &ast_ctx, StringLexer &type, bool for_expression) { - return BuildAggregate(ast_ctx, type, for_expression, '{', '}', + return BuildAggregate(ast_ctx, type, for_expression, _C_STRUCT_B, _C_STRUCT_E, clang::TTK_Struct); } clang::QualType AppleObjCTypeEncodingParser::BuildUnion( TypeSystemClang &ast_ctx, StringLexer &type, bool for_expression) { - return BuildAggregate(ast_ctx, type, for_expression, '(', ')', + return BuildAggregate(ast_ctx, type, for_expression, _C_UNION_B, _C_UNION_E, clang::TTK_Union); } @@ -148,11 +148,11 @@ clang::QualType AppleObjCTypeEncodingParser::BuildAggregate( clang::QualType AppleObjCTypeEncodingParser::BuildArray( TypeSystemClang &ast_ctx, StringLexer &type, bool for_expression) { - if (!type.NextIf('[')) + if (!type.NextIf(_C_ARY_B)) return clang::QualType(); uint32_t size = ReadNumber(type); clang::QualType element_type(BuildType(ast_ctx, type, for_expression)); - if (!type.NextIf(']')) + if (!type.NextIf(_C_ARY_E)) return clang::QualType(); CompilerType array_type(ast_ctx.CreateArrayType( CompilerType(&ast_ctx, element_type.getAsOpaquePtr()), size, false)); @@ -166,7 +166,7 @@ clang::QualType AppleObjCTypeEncodingParser::BuildArray( // dynamic typing will resolve things for us anyway clang::QualType AppleObjCTypeEncodingParser::BuildObjCObjectPointerType( TypeSystemClang &clang_ast_ctx, StringLexer &type, bool for_expression) { - if (!type.NextIf('@')) + if (!type.NextIf(_C_ID)) return clang::QualType(); clang::ASTContext &ast_ctx = clang_ast_ctx.getASTContext(); @@ -203,9 +203,9 @@ clang::QualType AppleObjCTypeEncodingParser::BuildObjCObjectPointerType( 2); // undo our consumption of the string and of the quotes name.clear(); break; - case '}': - case ')': - case ']': + case _C_STRUCT_E: + case _C_UNION_E: + case _C_ARY_E: case '"': // the quoted string is a class name – see the rule break; @@ -260,13 +260,13 @@ AppleObjCTypeEncodingParser::BuildType(TypeSystemClang &clang_ast_ctx, switch (type.Peek()) { default: break; - case '{': + case _C_STRUCT_B: return BuildStruct(clang_ast_ctx, type, for_expression); - case '[': + case _C_ARY_B: return BuildArray(clang_ast_ctx, type, for_expression); - case '(': + case _C_UNION_B: return BuildUnion(clang_ast_ctx, type, for_expression); - case '@': + case _C_ID: return BuildObjCObjectPointerType(clang_ast_ctx, type, for_expression); } @@ -274,46 +274,46 @@ AppleObjCTypeEncodingParser::BuildType(TypeSystemClang &clang_ast_ctx, default: type.PutBack(1); return clang::QualType(); - case 'c': + case _C_CHR: return ast_ctx.CharTy; - case 'i': + case _C_INT: return ast_ctx.IntTy; - case 's': + case _C_SHT: return ast_ctx.ShortTy; - case 'l': + case _C_LNG: return ast_ctx.getIntTypeForBitwidth(32, true); // this used to be done like this: // return clang_ast_ctx->GetIntTypeFromBitSize(32, true).GetQualType(); // which uses one of the constants if one is available, but we don't think // all this work is necessary. - case 'q': + case _C_LNG_LNG: return ast_ctx.LongLongTy; - case 'C': + case _C_UCHR: return ast_ctx.UnsignedCharTy; - case 'I': + case _C_UINT: return ast_ctx.UnsignedIntTy; - case 'S': + case _C_USHT: return ast_ctx.UnsignedShortTy; - case 'L': + case _C_ULNG: return ast_ctx.getIntTypeForBitwidth(32, false); - // see note for 'l' - case 'Q': + // see note for _C_LNG + case _C_ULNG_LNG: return ast_ctx.UnsignedLongLongTy; - case 'f': + case _C_FLT: return ast_ctx.FloatTy; - case 'd': + case _C_DBL: return ast_ctx.DoubleTy; - case 'B': + case _C_BOOL: return ast_ctx.BoolTy; - case 'v': + case _C_VOID: return ast_ctx.VoidTy; - case '*': + case _C_CHARPTR: return ast_ctx.getPointerType(ast_ctx.CharTy); - case '#': + case _C_CLASS: return ast_ctx.getObjCClassType(); - case ':': + case _C_SEL: return ast_ctx.getObjCSelType(); - case 'b': { + case _C_BFLD: { uint32_t size = ReadNumber(type); if (bitfield_bit_size) { *bitfield_bit_size = size; @@ -321,7 +321,7 @@ AppleObjCTypeEncodingParser::BuildType(TypeSystemClang &clang_ast_ctx, } else return clang::QualType(); } - case 'r': { + case _C_CONST: { clang::QualType target_type = BuildType(clang_ast_ctx, type, for_expression); if (target_type.isNull()) @@ -331,8 +331,8 @@ AppleObjCTypeEncodingParser::BuildType(TypeSystemClang &clang_ast_ctx, else return ast_ctx.getConstType(target_type); } - case '^': { - if (!for_expression && type.NextIf('?')) { + case _C_PTR: { + if (!for_expression && type.NextIf(_C_UNDEF)) { // if we are not supporting the concept of unknownAny, but what is being // created here is an unknownAny*, then we can just get away with a void* // this is theoretically wrong (in the same sense as 'theoretically @@ -350,7 +350,7 @@ AppleObjCTypeEncodingParser::BuildType(TypeSystemClang &clang_ast_ctx, return ast_ctx.getPointerType(target_type); } } - case '?': + case _C_UNDEF: return for_expression ? ast_ctx.UnknownAnyTy : clang::QualType(); } } diff --git a/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.h b/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.h index 6e533b591eca..57ed9c21faba 100644 --- a/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.h +++ b/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.h @@ -9,11 +9,11 @@ #ifndef LLDB_SOURCE_PLUGINS_LANGUAGERUNTIME_OBJC_APPLEOBJCRUNTIME_APPLEOBJCTYPEENCODINGPARSER_H #define LLDB_SOURCE_PLUGINS_LANGUAGERUNTIME_OBJC_APPLEOBJCRUNTIME_APPLEOBJCTYPEENCODINGPARSER_H -#include "clang/AST/ASTContext.h" - +#include "Plugins/Language/ObjC/ObjCConstants.h" +#include "Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.h" #include "lldb/lldb-private.h" -#include "Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.h" +#include "clang/AST/ASTContext.h" namespace lldb_private { class StringLexer; diff --git a/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.cpp b/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.cpp index 1dc8034c537a..f935ae7db8c0 100644 --- a/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.cpp @@ -12,6 +12,7 @@ #include "lldb/Expression/DiagnosticManager.h" #include "lldb/Expression/FunctionCaller.h" #include "lldb/Expression/UtilityFunction.h" +#include "lldb/Target/ABI.h" #include "lldb/Target/ExecutionContext.h" #include "lldb/Target/Process.h" #include "lldb/Target/Thread.h" @@ -134,6 +135,10 @@ bool AppleThreadPlanStepThroughObjCTrampoline::ShouldStop(Event *event_ptr) { target_addr_value); m_impl_function->DeallocateFunctionResults(exc_ctx, m_args_addr); lldb::addr_t target_addr = target_addr_value.GetScalar().ULongLong(); + + if (ABISP abi_sp = GetThread().GetProcess()->GetABI()) { + target_addr = abi_sp->FixCodeAddress(target_addr); + } Address target_so_addr; target_so_addr.SetOpcodeLoadAddress(target_addr, exc_ctx.GetTargetPtr()); Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP)); diff --git a/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.cpp b/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.cpp index 65bf3e6af626..0cc96e43e195 100644 --- a/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.cpp @@ -20,6 +20,7 @@ #include "lldb/Symbol/TypeList.h" #include "lldb/Symbol/Variable.h" #include "lldb/Target/Target.h" +#include "lldb/Target/ABI.h" #include "lldb/Utility/Log.h" #include "lldb/Utility/Timer.h" @@ -273,10 +274,17 @@ ObjCLanguageRuntime::ClassDescriptorSP ObjCLanguageRuntime::GetClassDescriptorFromISA(ObjCISA isa) { if (isa) { UpdateISAToDescriptorMap(); + ObjCLanguageRuntime::ISAToDescriptorIterator pos = m_isa_to_descriptor.find(isa); if (pos != m_isa_to_descriptor.end()) return pos->second; + + if (ABISP abi_sp = m_process->GetABI()) { + pos = m_isa_to_descriptor.find(abi_sp->FixCodeAddress(isa)); + if (pos != m_isa_to_descriptor.end()) + return pos->second; + } } return ClassDescriptorSP(); } diff --git a/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptExpressionOpts.cpp b/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptExpressionOpts.cpp index 08a752eaa888..c990c733d24c 100644 --- a/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptExpressionOpts.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptExpressionOpts.cpp @@ -14,7 +14,7 @@ #include "llvm/IR/Instructions.h" #include "llvm/IR/LegacyPassManager.h" #include "llvm/IR/Module.h" -#include "llvm/Support/TargetRegistry.h" +#include "llvm/MC/TargetRegistry.h" #include "llvm/Target/TargetMachine.h" #include "llvm/Target/TargetOptions.h" @@ -40,9 +40,8 @@ using namespace lldb_renderscript; // perform a fixup pass that removes those assumptions right before the module // is sent to be generated by the llvm backend. -namespace { -bool registerRSDefaultTargetOpts(clang::TargetOptions &proto, - const llvm::Triple::ArchType &arch) { +static bool registerRSDefaultTargetOpts(clang::TargetOptions &proto, + const llvm::Triple::ArchType &arch) { switch (arch) { case llvm::Triple::ArchType::x86: proto.Triple = "i686--linux-android"; @@ -75,7 +74,6 @@ bool registerRSDefaultTargetOpts(clang::TargetOptions &proto, } return true; } -} // end anonymous namespace bool RenderScriptRuntimeModulePass::runOnModule(llvm::Module &module) { bool changed_module = false; diff --git a/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptExpressionOpts.h b/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptExpressionOpts.h index 52da677128e2..e0b4f388dcc5 100644 --- a/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptExpressionOpts.h +++ b/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptExpressionOpts.h @@ -10,7 +10,7 @@ #define LLDB_SOURCE_PLUGINS_LANGUAGERUNTIME_RENDERSCRIPT_RENDERSCRIPTRUNTIME_RENDERSCRIPTEXPRESSIONOPTS_H #include "llvm/IR/Module.h" -#include "llvm/Support/TargetRegistry.h" +#include "llvm/MC/TargetRegistry.h" #include "llvm/Target/TargetMachine.h" #include "llvm/Target/TargetOptions.h" diff --git a/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.cpp b/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.cpp index 10ff5aa72b52..d6de65809c18 100644 --- a/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.cpp @@ -17,7 +17,6 @@ #include "lldb/DataFormatters/DumpValueObjectOptions.h" #include "lldb/Expression/UserExpression.h" #include "lldb/Host/OptionParser.h" -#include "lldb/Host/StringConvert.h" #include "lldb/Interpreter/CommandInterpreter.h" #include "lldb/Interpreter/CommandObjectMultiword.h" #include "lldb/Interpreter/CommandReturnObject.h" @@ -967,11 +966,6 @@ void RenderScriptRuntime::Terminate() { PluginManager::UnregisterPlugin(CreateInstance); } -lldb_private::ConstString RenderScriptRuntime::GetPluginNameStatic() { - static ConstString plugin_name("renderscript"); - return plugin_name; -} - RenderScriptRuntime::ModuleKind RenderScriptRuntime::GetModuleKind(const lldb::ModuleSP &module_sp) { if (module_sp) { @@ -1014,13 +1008,6 @@ void RenderScriptRuntime::ModulesDidLoad(const ModuleList &module_list) { } } -// PluginInterface protocol -lldb_private::ConstString RenderScriptRuntime::GetPluginName() { - return GetPluginNameStatic(); -} - -uint32_t RenderScriptRuntime::GetPluginVersion() { return 1; } - bool RenderScriptRuntime::GetDynamicTypeAndAddress( ValueObject &in_value, lldb::DynamicValueType use_dynamic, TypeAndOrName &class_type_or_name, Address &address, @@ -2660,7 +2647,7 @@ bool RenderScriptRuntime::SaveAllocation(Stream &strm, const uint32_t alloc_id, FileSpec file_spec(path); FileSystem::Instance().Resolve(file_spec); auto file = FileSystem::Instance().Open( - file_spec, File::eOpenOptionWrite | File::eOpenOptionCanCreate | + file_spec, File::eOpenOptionWriteOnly | File::eOpenOptionCanCreate | File::eOpenOptionTruncate); if (!file) { @@ -4568,10 +4555,8 @@ public: eLanguageTypeExtRenderScript)); const char *id_cstr = command.GetArgumentAtIndex(0); - bool success = false; - const uint32_t id = - StringConvert::ToUInt32(id_cstr, UINT32_MAX, 0, &success); - if (!success) { + uint32_t id; + if (!llvm::to_integer(id_cstr, id)) { result.AppendErrorWithFormat("invalid allocation id argument '%s'", id_cstr); return false; @@ -4585,8 +4570,9 @@ public: if (outfile_spec) { // Open output file std::string path = outfile_spec.GetPath(); - auto file = FileSystem::Instance().Open( - outfile_spec, File::eOpenOptionWrite | File::eOpenOptionCanCreate); + auto file = FileSystem::Instance().Open(outfile_spec, + File::eOpenOptionWriteOnly | + File::eOpenOptionCanCreate); if (file) { output_stream_storage = std::make_unique<StreamFile>(std::move(file.get())); @@ -4714,10 +4700,8 @@ public: eLanguageTypeExtRenderScript)); const char *id_cstr = command.GetArgumentAtIndex(0); - bool success = false; - const uint32_t id = - StringConvert::ToUInt32(id_cstr, UINT32_MAX, 0, &success); - if (!success) { + uint32_t id; + if (!llvm::to_integer(id_cstr, id)) { result.AppendErrorWithFormat("invalid allocation id argument '%s'", id_cstr); return false; @@ -4763,10 +4747,8 @@ public: eLanguageTypeExtRenderScript)); const char *id_cstr = command.GetArgumentAtIndex(0); - bool success = false; - const uint32_t id = - StringConvert::ToUInt32(id_cstr, UINT32_MAX, 0, &success); - if (!success) { + uint32_t id; + if (!llvm::to_integer(id_cstr, id)) { result.AppendErrorWithFormat("invalid allocation id argument '%s'", id_cstr); return false; diff --git a/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.h b/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.h index 2785c3b08125..4ddf996dedb2 100644 --- a/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.h +++ b/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.h @@ -318,7 +318,7 @@ public: static lldb::CommandObjectSP GetCommandObject(CommandInterpreter &interpreter); - static lldb_private::ConstString GetPluginNameStatic(); + static llvm::StringRef GetPluginNameStatic() { return "renderscript"; } static char ID; @@ -410,9 +410,7 @@ public: bool GetOverrideExprOptions(clang::TargetOptions &prototype); // PluginInterface protocol - lldb_private::ConstString GetPluginName() override; - - uint32_t GetPluginVersion() override; + llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); } static bool GetKernelCoordinate(lldb_renderscript::RSCoordinate &coord, Thread *thread_ptr); diff --git a/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptx86ABIFixups.cpp b/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptx86ABIFixups.cpp index f51190e0c82c..f3b7c9dd3edc 100644 --- a/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptx86ABIFixups.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptx86ABIFixups.cpp @@ -22,9 +22,8 @@ #include "lldb/Utility/Log.h" using namespace lldb_private; -namespace { -bool isRSAPICall(llvm::Module &module, llvm::CallInst *call_inst) { +static bool isRSAPICall(llvm::Module &module, llvm::CallInst *call_inst) { // TODO get the list of renderscript modules from lldb and check if // this llvm::Module calls into any of them. (void)module; @@ -38,7 +37,8 @@ bool isRSAPICall(llvm::Module &module, llvm::CallInst *call_inst) { return true; } -bool isRSLargeReturnCall(llvm::Module &module, llvm::CallInst *call_inst) { +static bool isRSLargeReturnCall(llvm::Module &module, + llvm::CallInst *call_inst) { // i686 and x86_64 returns for large vectors in the RenderScript API are not // handled as normal register pairs, but as a hidden sret type. This is not // reflected in the debug info or mangled symbol name, and the android ABI @@ -58,7 +58,7 @@ bool isRSLargeReturnCall(llvm::Module &module, llvm::CallInst *call_inst) { ->getPrimitiveSizeInBits() > 128; } -bool isRSAllocationPtrTy(const llvm::Type *type) { +static bool isRSAllocationPtrTy(const llvm::Type *type) { if (!type->isPointerTy()) return false; auto ptr_type = type->getPointerElementType(); @@ -67,7 +67,8 @@ bool isRSAllocationPtrTy(const llvm::Type *type) { ptr_type->getStructName().startswith("struct.rs_allocation"); } -bool isRSAllocationTyCallSite(llvm::Module &module, llvm::CallInst *call_inst) { +static bool isRSAllocationTyCallSite(llvm::Module &module, + llvm::CallInst *call_inst) { (void)module; if (!call_inst->hasByValArgument()) return false; @@ -77,7 +78,7 @@ bool isRSAllocationTyCallSite(llvm::Module &module, llvm::CallInst *call_inst) { return false; } -llvm::FunctionType *cloneToStructRetFnTy(llvm::CallInst *call_inst) { +static llvm::FunctionType *cloneToStructRetFnTy(llvm::CallInst *call_inst) { // on x86 StructReturn functions return a pointer to the return value, rather // than the return value itself // [ref](http://www.agner.org/optimize/calling_conventions.pdf section 6). We @@ -122,9 +123,9 @@ llvm::FunctionType *cloneToStructRetFnTy(llvm::CallInst *call_inst) { orig->isVarArg()); } -bool findRSCallSites(llvm::Module &module, - std::set<llvm::CallInst *> &rs_callsites, - bool (*predicate)(llvm::Module &, llvm::CallInst *)) { +static bool +findRSCallSites(llvm::Module &module, std::set<llvm::CallInst *> &rs_callsites, + bool (*predicate)(llvm::Module &, llvm::CallInst *)) { bool found = false; for (auto &func : module.getFunctionList()) @@ -143,7 +144,7 @@ bool findRSCallSites(llvm::Module &module, return found; } -bool fixupX86StructRetCalls(llvm::Module &module) { +static bool fixupX86StructRetCalls(llvm::Module &module) { bool changed = false; // changing a basic block while iterating over it seems to have some // undefined behaviour going on so we find all RS callsites first, then fix @@ -207,7 +208,7 @@ bool fixupX86StructRetCalls(llvm::Module &module) { return changed; } -bool fixupRSAllocationStructByValCalls(llvm::Module &module) { +static bool fixupRSAllocationStructByValCalls(llvm::Module &module) { // On x86_64, calls to functions in the RS runtime that take an // `rs_allocation` type argument are actually handled as by-ref params by // bcc, but appear to be passed by value by lldb (the callsite all use @@ -237,12 +238,11 @@ bool fixupRSAllocationStructByValCalls(llvm::Module &module) { llvm::AttributeList call_attribs = call_inst->getAttributes(); // iterate over the argument attributes - for (unsigned I = call_attribs.index_begin(); I != call_attribs.index_end(); - I++) { + for (unsigned I : call_attribs.indexes()) { // if this argument is passed by val - if (call_attribs.hasAttribute(I, llvm::Attribute::ByVal)) { + if (call_attribs.hasAttributeAtIndex(I, llvm::Attribute::ByVal)) { // strip away the byval attribute - call_inst->removeAttribute(I, llvm::Attribute::ByVal); + call_inst->removeAttributeAtIndex(I, llvm::Attribute::ByVal); changed = true; } } @@ -260,7 +260,6 @@ bool fixupRSAllocationStructByValCalls(llvm::Module &module) { } return changed; } -} // end anonymous namespace namespace lldb_private { namespace lldb_renderscript { diff --git a/contrib/llvm-project/lldb/source/Plugins/MemoryHistory/asan/MemoryHistoryASan.cpp b/contrib/llvm-project/lldb/source/Plugins/MemoryHistory/asan/MemoryHistoryASan.cpp index 7d9976285192..14d9c4024689 100644 --- a/contrib/llvm-project/lldb/source/Plugins/MemoryHistory/asan/MemoryHistoryASan.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/MemoryHistory/asan/MemoryHistoryASan.cpp @@ -56,11 +56,6 @@ void MemoryHistoryASan::Terminate() { PluginManager::UnregisterPlugin(CreateInstance); } -ConstString MemoryHistoryASan::GetPluginNameStatic() { - static ConstString g_name("asan"); - return g_name; -} - MemoryHistoryASan::MemoryHistoryASan(const ProcessSP &process_sp) { if (process_sp) m_process_wp = process_sp; diff --git a/contrib/llvm-project/lldb/source/Plugins/MemoryHistory/asan/MemoryHistoryASan.h b/contrib/llvm-project/lldb/source/Plugins/MemoryHistory/asan/MemoryHistoryASan.h index e9fe37d344a4..6563c3cd94a7 100644 --- a/contrib/llvm-project/lldb/source/Plugins/MemoryHistory/asan/MemoryHistoryASan.h +++ b/contrib/llvm-project/lldb/source/Plugins/MemoryHistory/asan/MemoryHistoryASan.h @@ -27,13 +27,9 @@ public: static void Terminate(); - static lldb_private::ConstString GetPluginNameStatic(); + static llvm::StringRef GetPluginNameStatic() { return "asan"; } - lldb_private::ConstString GetPluginName() override { - return GetPluginNameStatic(); - } - - uint32_t GetPluginVersion() override { return 1; } + llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); } lldb_private::HistoryThreads GetHistoryThreads(lldb::addr_t address) override; diff --git a/contrib/llvm-project/lldb/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.cpp b/contrib/llvm-project/lldb/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.cpp index 7ff917518b64..a2522372f5af 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.cpp @@ -274,15 +274,6 @@ void ObjectContainerBSDArchive::Terminate() { PluginManager::UnregisterPlugin(CreateInstance); } -lldb_private::ConstString ObjectContainerBSDArchive::GetPluginNameStatic() { - static ConstString g_name("bsd-archive"); - return g_name; -} - -const char *ObjectContainerBSDArchive::GetPluginDescriptionStatic() { - return "BSD Archive object container reader."; -} - ObjectContainer *ObjectContainerBSDArchive::CreateInstance( const lldb::ModuleSP &module_sp, DataBufferSP &data_sp, lldb::offset_t data_offset, const FileSpec *file, @@ -433,13 +424,6 @@ ObjectFileSP ObjectContainerBSDArchive::GetObjectFile(const FileSpec *file) { return ObjectFileSP(); } -// PluginInterface protocol -lldb_private::ConstString ObjectContainerBSDArchive::GetPluginName() { - return GetPluginNameStatic(); -} - -uint32_t ObjectContainerBSDArchive::GetPluginVersion() { return 1; } - size_t ObjectContainerBSDArchive::GetModuleSpecifications( const lldb_private::FileSpec &file, lldb::DataBufferSP &data_sp, lldb::offset_t data_offset, lldb::offset_t file_offset, diff --git a/contrib/llvm-project/lldb/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.h b/contrib/llvm-project/lldb/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.h index 9830e9b5d1b2..21106d7b8590 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.h +++ b/contrib/llvm-project/lldb/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.h @@ -36,9 +36,11 @@ public: static void Terminate(); - static lldb_private::ConstString GetPluginNameStatic(); + static llvm::StringRef GetPluginNameStatic() { return "bsd-archive"; } - static const char *GetPluginDescriptionStatic(); + static llvm::StringRef GetPluginDescriptionStatic() { + return "BSD Archive object container reader."; + } static lldb_private::ObjectContainer * CreateInstance(const lldb::ModuleSP &module_sp, lldb::DataBufferSP &data_sp, @@ -68,9 +70,7 @@ public: lldb::ObjectFileSP GetObjectFile(const lldb_private::FileSpec *file) override; // PluginInterface protocol - lldb_private::ConstString GetPluginName() override; - - uint32_t GetPluginVersion() override; + llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); } protected: struct Object { diff --git a/contrib/llvm-project/lldb/source/Plugins/ObjectFile/Breakpad/BreakpadRecords.cpp b/contrib/llvm-project/lldb/source/Plugins/ObjectFile/Breakpad/BreakpadRecords.cpp index bd8eeedce57d..24941be515de 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ObjectFile/Breakpad/BreakpadRecords.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/ObjectFile/Breakpad/BreakpadRecords.cpp @@ -23,6 +23,8 @@ enum class Token { CodeID, File, Func, + Inline, + InlineOrigin, Public, Stack, CFI, @@ -41,6 +43,8 @@ template <> Token stringTo<Token>(llvm::StringRef Str) { .Case("CODE_ID", Token::CodeID) .Case("FILE", Token::File) .Case("FUNC", Token::Func) + .Case("INLINE", Token::Inline) + .Case("INLINE_ORIGIN", Token::InlineOrigin) .Case("PUBLIC", Token::Public) .Case("STACK", Token::Stack) .Case("CFI", Token::CFI) @@ -145,7 +149,10 @@ llvm::Optional<Record::Kind> Record::classify(llvm::StringRef Line) { default: return llvm::None; } - + case Token::Inline: + return Record::Inline; + case Token::InlineOrigin: + return Record::InlineOrigin; case Token::Unknown: // Optimistically assume that any unrecognised token means this is a line // record, those don't have a special keyword and start directly with a @@ -216,9 +223,11 @@ llvm::raw_ostream &breakpad::operator<<(llvm::raw_ostream &OS, return OS << "INFO CODE_ID " << R.ID.GetAsString(); } -llvm::Optional<FileRecord> FileRecord::parse(llvm::StringRef Line) { - // FILE number name - if (consume<Token>(Line) != Token::File) +template <typename T> +static llvm::Optional<T> parseNumberName(llvm::StringRef Line, + Token TokenType) { + // TOKEN number name + if (consume<Token>(Line) != TokenType) return llvm::None; llvm::StringRef Str; @@ -231,7 +240,12 @@ llvm::Optional<FileRecord> FileRecord::parse(llvm::StringRef Line) { if (Name.empty()) return llvm::None; - return FileRecord(Number, Name); + return T(Number, Name); +} + +llvm::Optional<FileRecord> FileRecord::parse(llvm::StringRef Line) { + // FILE number name + return parseNumberName<FileRecord>(Line, Token::File); } llvm::raw_ostream &breakpad::operator<<(llvm::raw_ostream &OS, @@ -239,6 +253,17 @@ llvm::raw_ostream &breakpad::operator<<(llvm::raw_ostream &OS, return OS << "FILE " << R.Number << " " << R.Name; } +llvm::Optional<InlineOriginRecord> +InlineOriginRecord::parse(llvm::StringRef Line) { + // INLINE_ORIGIN number name + return parseNumberName<InlineOriginRecord>(Line, Token::InlineOrigin); +} + +llvm::raw_ostream &breakpad::operator<<(llvm::raw_ostream &OS, + const InlineOriginRecord &R) { + return OS << "INLINE_ORIGIN " << R.Number << " " << R.Name; +} + static bool parsePublicOrFunc(llvm::StringRef Line, bool &Multiple, lldb::addr_t &Address, lldb::addr_t *Size, lldb::addr_t &ParamSize, llvm::StringRef &Name) { @@ -299,6 +324,58 @@ llvm::raw_ostream &breakpad::operator<<(llvm::raw_ostream &OS, R.ParamSize, R.Name); } +llvm::Optional<InlineRecord> InlineRecord::parse(llvm::StringRef Line) { + // INLINE inline_nest_level call_site_line call_site_file_num origin_num + // [address size]+ + if (consume<Token>(Line) != Token::Inline) + return llvm::None; + + llvm::SmallVector<llvm::StringRef> Tokens; + SplitString(Line, Tokens, " "); + if (Tokens.size() < 6 || Tokens.size() % 2 == 1) + return llvm::None; + + size_t InlineNestLevel; + uint32_t CallSiteLineNum; + size_t CallSiteFileNum; + size_t OriginNum; + if (!(to_integer(Tokens[0], InlineNestLevel) && + to_integer(Tokens[1], CallSiteLineNum) && + to_integer(Tokens[2], CallSiteFileNum) && + to_integer(Tokens[3], OriginNum))) + return llvm::None; + + InlineRecord Record = InlineRecord(InlineNestLevel, CallSiteLineNum, + CallSiteFileNum, OriginNum); + for (size_t i = 4; i < Tokens.size(); i += 2) { + lldb::addr_t Address; + if (!to_integer(Tokens[i], Address, 16)) + return llvm::None; + lldb::addr_t Size; + if (!to_integer(Tokens[i + 1].trim(), Size, 16)) + return llvm::None; + Record.Ranges.emplace_back(Address, Size); + } + return Record; +} + +bool breakpad::operator==(const InlineRecord &L, const InlineRecord &R) { + return L.InlineNestLevel == R.InlineNestLevel && + L.CallSiteLineNum == R.CallSiteLineNum && + L.CallSiteFileNum == R.CallSiteFileNum && L.OriginNum == R.OriginNum && + L.Ranges == R.Ranges; +} + +llvm::raw_ostream &breakpad::operator<<(llvm::raw_ostream &OS, + const InlineRecord &R) { + OS << llvm::formatv("INLINE {0} {1} {2} {3}", R.InlineNestLevel, + R.CallSiteLineNum, R.CallSiteFileNum, R.OriginNum); + for (const auto &range : R.Ranges) { + OS << llvm::formatv(" {0:x-} {1:x-}", range.first, range.second); + } + return OS; +} + llvm::Optional<LineRecord> LineRecord::parse(llvm::StringRef Line) { lldb::addr_t Address; llvm::StringRef Str; @@ -490,6 +567,10 @@ llvm::StringRef breakpad::toString(Record::Kind K) { return "FILE"; case Record::Func: return "FUNC"; + case Record::Inline: + return "INLINE"; + case Record::InlineOrigin: + return "INLINE_ORIGIN"; case Record::Line: return "LINE"; case Record::Public: diff --git a/contrib/llvm-project/lldb/source/Plugins/ObjectFile/Breakpad/BreakpadRecords.h b/contrib/llvm-project/lldb/source/Plugins/ObjectFile/Breakpad/BreakpadRecords.h index 1620a1210b84..8a11323d521c 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ObjectFile/Breakpad/BreakpadRecords.h +++ b/contrib/llvm-project/lldb/source/Plugins/ObjectFile/Breakpad/BreakpadRecords.h @@ -20,7 +20,18 @@ namespace breakpad { class Record { public: - enum Kind { Module, Info, File, Func, Line, Public, StackCFI, StackWin }; + enum Kind { + Module, + Info, + File, + Func, + Inline, + InlineOrigin, + Line, + Public, + StackCFI, + StackWin + }; /// Attempt to guess the kind of the record present in the argument without /// doing a full parse. The returned kind will always be correct for valid @@ -89,6 +100,23 @@ inline bool operator==(const FileRecord &L, const FileRecord &R) { } llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const FileRecord &R); +class InlineOriginRecord : public Record { +public: + static llvm::Optional<InlineOriginRecord> parse(llvm::StringRef Line); + InlineOriginRecord(size_t Number, llvm::StringRef Name) + : Record(InlineOrigin), Number(Number), Name(Name) {} + + size_t Number; + llvm::StringRef Name; +}; + +inline bool operator==(const InlineOriginRecord &L, + const InlineOriginRecord &R) { + return L.Number == R.Number && L.Name == R.Name; +} +llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, + const InlineOriginRecord &R); + class FuncRecord : public Record { public: static llvm::Optional<FuncRecord> parse(llvm::StringRef Line); @@ -107,6 +135,26 @@ public: bool operator==(const FuncRecord &L, const FuncRecord &R); llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const FuncRecord &R); +class InlineRecord : public Record { +public: + static llvm::Optional<InlineRecord> parse(llvm::StringRef Line); + InlineRecord(size_t InlineNestLevel, uint32_t CallSiteLineNum, + size_t CallSiteFileNum, size_t OriginNum) + : Record(Inline), InlineNestLevel(InlineNestLevel), + CallSiteLineNum(CallSiteLineNum), CallSiteFileNum(CallSiteFileNum), + OriginNum(OriginNum) {} + + size_t InlineNestLevel; + uint32_t CallSiteLineNum; + size_t CallSiteFileNum; + size_t OriginNum; + // A vector of address range covered by this inline + std::vector<std::pair<lldb::addr_t, lldb::addr_t>> Ranges; +}; + +bool operator==(const InlineRecord &L, const InlineRecord &R); +llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const InlineRecord &R); + class LineRecord : public Record { public: static llvm::Optional<LineRecord> parse(llvm::StringRef Line); diff --git a/contrib/llvm-project/lldb/source/Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.cpp b/contrib/llvm-project/lldb/source/Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.cpp index 7a9163ddb880..bad730512ff4 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.cpp @@ -56,11 +56,6 @@ void ObjectFileBreakpad::Terminate() { PluginManager::UnregisterPlugin(CreateInstance); } -ConstString ObjectFileBreakpad::GetPluginNameStatic() { - static ConstString g_name("breakpad"); - return g_name; -} - ObjectFile *ObjectFileBreakpad::CreateInstance( const ModuleSP &module_sp, DataBufferSP &data_sp, offset_t data_offset, const FileSpec *file, offset_t file_offset, offset_t length) { @@ -153,9 +148,9 @@ void ObjectFileBreakpad::CreateSections(SectionList &unified_section_list) { std::tie(line, text) = text.split('\n'); llvm::Optional<Record::Kind> next_section = Record::classify(line); - if (next_section == Record::Line) { - // Line records logically belong to the preceding Func record, so we put - // them in the same section. + if (next_section == Record::Line || next_section == Record::Inline) { + // Line/Inline records logically belong to the preceding Func record, so + // we put them in the same section. next_section = Record::Func; } if (next_section == current_section) diff --git a/contrib/llvm-project/lldb/source/Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.h b/contrib/llvm-project/lldb/source/Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.h index 8724feaa422d..c320c7ad3e2e 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.h +++ b/contrib/llvm-project/lldb/source/Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.h @@ -21,7 +21,7 @@ public: static void Initialize(); static void Terminate(); - static ConstString GetPluginNameStatic(); + static llvm::StringRef GetPluginNameStatic() { return "breakpad"; } static const char *GetPluginDescriptionStatic() { return "Breakpad object file reader."; } @@ -44,9 +44,7 @@ public: ModuleSpecList &specs); // PluginInterface protocol - ConstString GetPluginName() override { return GetPluginNameStatic(); } - - uint32_t GetPluginVersion() override { return 1; } + llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); } // LLVM RTTI support static char ID; diff --git a/contrib/llvm-project/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp b/contrib/llvm-project/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp index a5e86f0c2c1b..8e0f228a988f 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp @@ -55,36 +55,36 @@ using namespace llvm::ELF; LLDB_PLUGIN_DEFINE(ObjectFileELF) -namespace { - // ELF note owner definitions -const char *const LLDB_NT_OWNER_FREEBSD = "FreeBSD"; -const char *const LLDB_NT_OWNER_GNU = "GNU"; -const char *const LLDB_NT_OWNER_NETBSD = "NetBSD"; -const char *const LLDB_NT_OWNER_NETBSDCORE = "NetBSD-CORE"; -const char *const LLDB_NT_OWNER_OPENBSD = "OpenBSD"; -const char *const LLDB_NT_OWNER_ANDROID = "Android"; -const char *const LLDB_NT_OWNER_CORE = "CORE"; -const char *const LLDB_NT_OWNER_LINUX = "LINUX"; +static const char *const LLDB_NT_OWNER_FREEBSD = "FreeBSD"; +static const char *const LLDB_NT_OWNER_GNU = "GNU"; +static const char *const LLDB_NT_OWNER_NETBSD = "NetBSD"; +static const char *const LLDB_NT_OWNER_NETBSDCORE = "NetBSD-CORE"; +static const char *const LLDB_NT_OWNER_OPENBSD = "OpenBSD"; +static const char *const LLDB_NT_OWNER_ANDROID = "Android"; +static const char *const LLDB_NT_OWNER_CORE = "CORE"; +static const char *const LLDB_NT_OWNER_LINUX = "LINUX"; // ELF note type definitions -const elf_word LLDB_NT_FREEBSD_ABI_TAG = 0x01; -const elf_word LLDB_NT_FREEBSD_ABI_SIZE = 4; +static const elf_word LLDB_NT_FREEBSD_ABI_TAG = 0x01; +static const elf_word LLDB_NT_FREEBSD_ABI_SIZE = 4; -const elf_word LLDB_NT_GNU_ABI_TAG = 0x01; -const elf_word LLDB_NT_GNU_ABI_SIZE = 16; +static const elf_word LLDB_NT_GNU_ABI_TAG = 0x01; +static const elf_word LLDB_NT_GNU_ABI_SIZE = 16; -const elf_word LLDB_NT_GNU_BUILD_ID_TAG = 0x03; +static const elf_word LLDB_NT_GNU_BUILD_ID_TAG = 0x03; -const elf_word LLDB_NT_NETBSD_IDENT_TAG = 1; -const elf_word LLDB_NT_NETBSD_IDENT_DESCSZ = 4; -const elf_word LLDB_NT_NETBSD_IDENT_NAMESZ = 7; -const elf_word LLDB_NT_NETBSD_PROCINFO = 1; +static const elf_word LLDB_NT_NETBSD_IDENT_TAG = 1; +static const elf_word LLDB_NT_NETBSD_IDENT_DESCSZ = 4; +static const elf_word LLDB_NT_NETBSD_IDENT_NAMESZ = 7; +static const elf_word LLDB_NT_NETBSD_PROCINFO = 1; // GNU ABI note OS constants -const elf_word LLDB_NT_GNU_ABI_OS_LINUX = 0x00; -const elf_word LLDB_NT_GNU_ABI_OS_HURD = 0x01; -const elf_word LLDB_NT_GNU_ABI_OS_SOLARIS = 0x02; +static const elf_word LLDB_NT_GNU_ABI_OS_LINUX = 0x00; +static const elf_word LLDB_NT_GNU_ABI_OS_HURD = 0x01; +static const elf_word LLDB_NT_GNU_ABI_OS_SOLARIS = 0x02; + +namespace { //===----------------------------------------------------------------------===// /// \class ELFRelocation @@ -125,6 +125,7 @@ private: RelocUnion reloc; }; +} // end anonymous namespace ELFRelocation::ELFRelocation(unsigned type) { if (type == DT_REL || type == SHT_REL) @@ -208,8 +209,6 @@ unsigned ELFRelocation::RelocAddend64(const ELFRelocation &rel) { return rel.reloc.get<ELFRela *>()->r_addend; } -} // end anonymous namespace - static user_id_t SegmentID(size_t PHdrIndex) { return ~user_id_t(PHdrIndex); } @@ -335,15 +334,6 @@ void ObjectFileELF::Terminate() { PluginManager::UnregisterPlugin(CreateInstance); } -lldb_private::ConstString ObjectFileELF::GetPluginNameStatic() { - static ConstString g_name("elf"); - return g_name; -} - -const char *ObjectFileELF::GetPluginDescriptionStatic() { - return "ELF object file reader."; -} - ObjectFile *ObjectFileELF::CreateInstance(const lldb::ModuleSP &module_sp, DataBufferSP &data_sp, lldb::offset_t data_offset, @@ -634,12 +624,6 @@ size_t ObjectFileELF::GetModuleSpecifications( return specs.GetSize() - initial_count; } -// PluginInterface protocol -lldb_private::ConstString ObjectFileELF::GetPluginName() { - return GetPluginNameStatic(); -} - -uint32_t ObjectFileELF::GetPluginVersion() { return m_plugin_version; } // ObjectFile protocol ObjectFileELF::ObjectFileELF(const lldb::ModuleSP &module_sp, @@ -2708,9 +2692,6 @@ Symtab *ObjectFileELF::GetSymtab() { if (!module_sp) return nullptr; - Progress progress(llvm::formatv("Parsing symbol table for {0}", - m_file.GetFilename().AsCString("<Unknown>"))); - // We always want to use the main object file so we (hopefully) only have one // cached copy of our symtab, dynamic sections, etc. ObjectFile *module_obj_file = module_sp->GetObjectFile(); @@ -2718,6 +2699,10 @@ Symtab *ObjectFileELF::GetSymtab() { return module_obj_file->GetSymtab(); if (m_symtab_up == nullptr) { + Progress progress( + llvm::formatv("Parsing symbol table for {0}", + m_file.GetFilename().AsCString("<Unknown>"))); + ElapsedTime elapsed(module_sp->GetSymtabParseTime()); SectionList *section_list = module_sp->GetSectionList(); if (!section_list) return nullptr; diff --git a/contrib/llvm-project/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.h b/contrib/llvm-project/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.h index e678c2f5f011..5738e5cf60d5 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.h +++ b/contrib/llvm-project/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.h @@ -61,9 +61,11 @@ public: static void Terminate(); - static lldb_private::ConstString GetPluginNameStatic(); + static llvm::StringRef GetPluginNameStatic() { return "elf"; } - static const char *GetPluginDescriptionStatic(); + static llvm::StringRef GetPluginDescriptionStatic() { + return "ELF object file reader."; + } static lldb_private::ObjectFile * CreateInstance(const lldb::ModuleSP &module_sp, lldb::DataBufferSP &data_sp, @@ -85,9 +87,7 @@ public: lldb::addr_t length); // PluginInterface protocol - lldb_private::ConstString GetPluginName() override; - - uint32_t GetPluginVersion() override; + llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); } // LLVM RTTI support static char ID; diff --git a/contrib/llvm-project/lldb/source/Plugins/ObjectFile/JIT/ObjectFileJIT.cpp b/contrib/llvm-project/lldb/source/Plugins/ObjectFile/JIT/ObjectFileJIT.cpp index f93ac9261afd..bec0099517c8 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ObjectFile/JIT/ObjectFileJIT.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/ObjectFile/JIT/ObjectFileJIT.cpp @@ -53,15 +53,6 @@ void ObjectFileJIT::Terminate() { PluginManager::UnregisterPlugin(CreateInstance); } -lldb_private::ConstString ObjectFileJIT::GetPluginNameStatic() { - static ConstString g_name("jit"); - return g_name; -} - -const char *ObjectFileJIT::GetPluginDescriptionStatic() { - return "JIT code object file"; -} - ObjectFile *ObjectFileJIT::CreateInstance(const lldb::ModuleSP &module_sp, DataBufferSP &data_sp, lldb::offset_t data_offset, @@ -120,6 +111,7 @@ Symtab *ObjectFileJIT::GetSymtab() { if (module_sp) { std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex()); if (m_symtab_up == nullptr) { + ElapsedTime elapsed(module_sp->GetSymtabParseTime()); m_symtab_up = std::make_unique<Symtab>(this); std::lock_guard<std::recursive_mutex> symtab_guard( m_symtab_up->GetMutex()); @@ -199,13 +191,6 @@ ArchSpec ObjectFileJIT::GetArchitecture() { return ArchSpec(); } -// PluginInterface protocol -lldb_private::ConstString ObjectFileJIT::GetPluginName() { - return GetPluginNameStatic(); -} - -uint32_t ObjectFileJIT::GetPluginVersion() { return 1; } - bool ObjectFileJIT::SetLoadAddress(Target &target, lldb::addr_t value, bool value_is_offset) { size_t num_loaded_sections = 0; diff --git a/contrib/llvm-project/lldb/source/Plugins/ObjectFile/JIT/ObjectFileJIT.h b/contrib/llvm-project/lldb/source/Plugins/ObjectFile/JIT/ObjectFileJIT.h index a3a1acea916a..03ac001988a0 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ObjectFile/JIT/ObjectFileJIT.h +++ b/contrib/llvm-project/lldb/source/Plugins/ObjectFile/JIT/ObjectFileJIT.h @@ -26,9 +26,11 @@ public: static void Terminate(); - static lldb_private::ConstString GetPluginNameStatic(); + static llvm::StringRef GetPluginNameStatic() { return "jit"; } - static const char *GetPluginDescriptionStatic(); + static llvm::StringRef GetPluginDescriptionStatic() { + return "JIT code object file"; + } static lldb_private::ObjectFile * CreateInstance(const lldb::ModuleSP &module_sp, lldb::DataBufferSP &data_sp, @@ -96,9 +98,7 @@ public: ObjectFile::Strata CalculateStrata() override; // PluginInterface protocol - lldb_private::ConstString GetPluginName() override; - - uint32_t GetPluginVersion() override; + llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); } protected: lldb::ObjectFileJITDelegateWP m_delegate_wp; diff --git a/contrib/llvm-project/lldb/source/Plugins/ObjectFile/Minidump/MinidumpFileBuilder.cpp b/contrib/llvm-project/lldb/source/Plugins/ObjectFile/Minidump/MinidumpFileBuilder.cpp new file mode 100644 index 000000000000..a70e6a079f76 --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/ObjectFile/Minidump/MinidumpFileBuilder.cpp @@ -0,0 +1,772 @@ +//===-- MinidumpFileBuilder.cpp -------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "MinidumpFileBuilder.h" + +#include "Plugins/Process/minidump/RegisterContextMinidump_x86_64.h" + +#include "lldb/Core/Module.h" +#include "lldb/Core/ModuleList.h" +#include "lldb/Core/Section.h" +#include "lldb/Target/MemoryRegionInfo.h" +#include "lldb/Target/Process.h" +#include "lldb/Target/RegisterContext.h" +#include "lldb/Target/StopInfo.h" +#include "lldb/Target/ThreadList.h" +#include "lldb/Utility/DataExtractor.h" +#include "lldb/Utility/RegisterValue.h" + +#include "llvm/ADT/StringRef.h" +#include "llvm/BinaryFormat/Minidump.h" +#include "llvm/Support/ConvertUTF.h" +#include "llvm/Support/Error.h" + +#include "Plugins/Process/minidump/MinidumpTypes.h" + +#include <cinttypes> + +using namespace lldb; +using namespace lldb_private; +using namespace llvm::minidump; + +void MinidumpFileBuilder::AddDirectory(StreamType type, size_t stream_size) { + LocationDescriptor loc; + loc.DataSize = static_cast<llvm::support::ulittle32_t>(stream_size); + // Stream will begin at the current end of data section + loc.RVA = static_cast<llvm::support::ulittle32_t>(GetCurrentDataEndOffset()); + + Directory dir; + dir.Type = static_cast<llvm::support::little_t<StreamType>>(type); + dir.Location = loc; + + m_directories.push_back(dir); +} + +Status MinidumpFileBuilder::AddSystemInfo(const llvm::Triple &target_triple) { + Status error; + AddDirectory(StreamType::SystemInfo, sizeof(llvm::minidump::SystemInfo)); + + llvm::minidump::ProcessorArchitecture arch; + switch (target_triple.getArch()) { + case llvm::Triple::ArchType::x86_64: + arch = ProcessorArchitecture::AMD64; + break; + case llvm::Triple::ArchType::x86: + arch = ProcessorArchitecture::X86; + break; + case llvm::Triple::ArchType::arm: + arch = ProcessorArchitecture::ARM; + break; + case llvm::Triple::ArchType::aarch64: + arch = ProcessorArchitecture::ARM64; + break; + case llvm::Triple::ArchType::mips64: + case llvm::Triple::ArchType::mips64el: + case llvm::Triple::ArchType::mips: + case llvm::Triple::ArchType::mipsel: + arch = ProcessorArchitecture::MIPS; + break; + case llvm::Triple::ArchType::ppc64: + case llvm::Triple::ArchType::ppc: + case llvm::Triple::ArchType::ppc64le: + arch = ProcessorArchitecture::PPC; + break; + default: + error.SetErrorStringWithFormat("Architecture %s not supported.", + target_triple.getArchName().str().c_str()); + return error; + }; + + llvm::support::little_t<OSPlatform> platform_id; + switch (target_triple.getOS()) { + case llvm::Triple::OSType::Linux: + if (target_triple.getEnvironment() == + llvm::Triple::EnvironmentType::Android) + platform_id = OSPlatform::Android; + else + platform_id = OSPlatform::Linux; + break; + case llvm::Triple::OSType::Win32: + platform_id = OSPlatform::Win32NT; + break; + case llvm::Triple::OSType::MacOSX: + platform_id = OSPlatform::MacOSX; + break; + case llvm::Triple::OSType::IOS: + platform_id = OSPlatform::IOS; + break; + default: + error.SetErrorStringWithFormat("OS %s not supported.", + target_triple.getOSName().str().c_str()); + return error; + }; + + llvm::minidump::SystemInfo sys_info; + sys_info.ProcessorArch = + static_cast<llvm::support::little_t<ProcessorArchitecture>>(arch); + // Global offset to beginning of a csd_string in a data section + sys_info.CSDVersionRVA = static_cast<llvm::support::ulittle32_t>( + GetCurrentDataEndOffset() + sizeof(llvm::minidump::SystemInfo)); + sys_info.PlatformId = platform_id; + m_data.AppendData(&sys_info, sizeof(llvm::minidump::SystemInfo)); + + std::string csd_string = ""; + + error = WriteString(csd_string, &m_data); + if (error.Fail()) { + error.SetErrorString("Unable to convert the csd string to UTF16."); + return error; + } + + return error; +} + +Status WriteString(const std::string &to_write, + lldb_private::DataBufferHeap *buffer) { + Status error; + // let the StringRef eat also null termination char + llvm::StringRef to_write_ref(to_write.c_str(), to_write.size() + 1); + llvm::SmallVector<llvm::UTF16, 128> to_write_utf16; + + bool converted = convertUTF8ToUTF16String(to_write_ref, to_write_utf16); + if (!converted) { + error.SetErrorStringWithFormat( + "Unable to convert the string to UTF16. Failed to convert %s", + to_write.c_str()); + return error; + } + + // size of the UTF16 string should be written without the null termination + // character that is stored in 2 bytes + llvm::support::ulittle32_t to_write_size(to_write_utf16.size_in_bytes() - 2); + + buffer->AppendData(&to_write_size, sizeof(llvm::support::ulittle32_t)); + buffer->AppendData(to_write_utf16.data(), to_write_utf16.size_in_bytes()); + + return error; +} + +llvm::Expected<uint64_t> getModuleFileSize(Target &target, + const ModuleSP &mod) { + SectionSP sect_sp = mod->GetObjectFile()->GetBaseAddress().GetSection(); + uint64_t SizeOfImage = 0; + + if (!sect_sp) { + return llvm::createStringError(std::errc::operation_not_supported, + "Couldn't obtain the section information."); + } + lldb::addr_t sect_addr = sect_sp->GetLoadBaseAddress(&target); + // Use memory size since zero fill sections, like ".bss", will be smaller on + // disk. + lldb::addr_t sect_size = sect_sp->GetByteSize(); + // This will usually be zero, but make sure to calculate the BaseOfImage + // offset. + const lldb::addr_t base_sect_offset = + mod->GetObjectFile()->GetBaseAddress().GetLoadAddress(&target) - + sect_addr; + SizeOfImage = sect_size - base_sect_offset; + lldb::addr_t next_sect_addr = sect_addr + sect_size; + Address sect_so_addr; + target.ResolveLoadAddress(next_sect_addr, sect_so_addr); + lldb::SectionSP next_sect_sp = sect_so_addr.GetSection(); + while (next_sect_sp && + next_sect_sp->GetLoadBaseAddress(&target) == next_sect_addr) { + sect_size = sect_sp->GetByteSize(); + SizeOfImage += sect_size; + next_sect_addr += sect_size; + target.ResolveLoadAddress(next_sect_addr, sect_so_addr); + next_sect_sp = sect_so_addr.GetSection(); + } + + return SizeOfImage; +} + +// ModuleList stream consists of a number of modules, followed by an array +// of llvm::minidump::Module's structures. Every structure informs about a +// single module. Additional data of variable length, such as module's names, +// are stored just after the ModuleList stream. The llvm::minidump::Module +// structures point to this helper data by global offset. +Status MinidumpFileBuilder::AddModuleList(Target &target) { + constexpr size_t minidump_module_size = sizeof(llvm::minidump::Module); + Status error; + + const ModuleList &modules = target.GetImages(); + llvm::support::ulittle32_t modules_count = + static_cast<llvm::support::ulittle32_t>(modules.GetSize()); + + // This helps us with getting the correct global offset in minidump + // file later, when we will be setting up offsets from the + // the llvm::minidump::Module's structures into helper data + size_t size_before = GetCurrentDataEndOffset(); + + // This is the size of the main part of the ModuleList stream. + // It consists of a module number and corresponding number of + // structs describing individual modules + size_t module_stream_size = + sizeof(llvm::support::ulittle32_t) + modules_count * minidump_module_size; + + // Adding directory describing this stream. + AddDirectory(StreamType::ModuleList, module_stream_size); + + m_data.AppendData(&modules_count, sizeof(llvm::support::ulittle32_t)); + + // Temporary storage for the helper data (of variable length) + // as these cannot be dumped to m_data before dumping entire + // array of module structures. + DataBufferHeap helper_data; + + for (size_t i = 0; i < modules_count; ++i) { + ModuleSP mod = modules.GetModuleAtIndex(i); + std::string module_name = mod->GetSpecificationDescription(); + auto maybe_mod_size = getModuleFileSize(target, mod); + if (!maybe_mod_size) { + error.SetErrorStringWithFormat("Unable to get the size of module %s.", + module_name.c_str()); + return error; + } + + uint64_t mod_size = std::move(*maybe_mod_size); + + llvm::support::ulittle32_t signature = + static_cast<llvm::support::ulittle32_t>( + static_cast<uint32_t>(minidump::CvSignature::ElfBuildId)); + auto uuid = mod->GetUUID().GetBytes(); + + VSFixedFileInfo info; + info.Signature = static_cast<llvm::support::ulittle32_t>(0u); + info.StructVersion = static_cast<llvm::support::ulittle32_t>(0u); + info.FileVersionHigh = static_cast<llvm::support::ulittle32_t>(0u); + info.FileVersionLow = static_cast<llvm::support::ulittle32_t>(0u); + info.ProductVersionHigh = static_cast<llvm::support::ulittle32_t>(0u); + info.ProductVersionLow = static_cast<llvm::support::ulittle32_t>(0u); + info.FileFlagsMask = static_cast<llvm::support::ulittle32_t>(0u); + info.FileFlags = static_cast<llvm::support::ulittle32_t>(0u); + info.FileOS = static_cast<llvm::support::ulittle32_t>(0u); + info.FileType = static_cast<llvm::support::ulittle32_t>(0u); + info.FileSubtype = static_cast<llvm::support::ulittle32_t>(0u); + info.FileDateHigh = static_cast<llvm::support::ulittle32_t>(0u); + info.FileDateLow = static_cast<llvm::support::ulittle32_t>(0u); + + LocationDescriptor ld; + ld.DataSize = static_cast<llvm::support::ulittle32_t>(0u); + ld.RVA = static_cast<llvm::support::ulittle32_t>(0u); + + // Setting up LocationDescriptor for uuid string. The global offset into + // minidump file is calculated. + LocationDescriptor ld_cv; + ld_cv.DataSize = static_cast<llvm::support::ulittle32_t>( + sizeof(llvm::support::ulittle32_t) + uuid.size()); + ld_cv.RVA = static_cast<llvm::support::ulittle32_t>( + size_before + module_stream_size + helper_data.GetByteSize()); + + helper_data.AppendData(&signature, sizeof(llvm::support::ulittle32_t)); + helper_data.AppendData(uuid.begin(), uuid.size()); + + llvm::minidump::Module m; + m.BaseOfImage = static_cast<llvm::support::ulittle64_t>( + mod->GetObjectFile()->GetBaseAddress().GetLoadAddress(&target)); + m.SizeOfImage = static_cast<llvm::support::ulittle32_t>(mod_size); + m.Checksum = static_cast<llvm::support::ulittle32_t>(0); + m.TimeDateStamp = static_cast<llvm::support::ulittle32_t>(std::time(0)); + m.ModuleNameRVA = static_cast<llvm::support::ulittle32_t>( + size_before + module_stream_size + helper_data.GetByteSize()); + m.VersionInfo = info; + m.CvRecord = ld_cv; + m.MiscRecord = ld; + + error = WriteString(module_name, &helper_data); + + if (error.Fail()) + return error; + + m_data.AppendData(&m, sizeof(llvm::minidump::Module)); + } + + m_data.AppendData(helper_data.GetBytes(), helper_data.GetByteSize()); + return error; +} + +uint16_t read_register_u16_raw(RegisterContext *reg_ctx, + const std::string ®_name) { + const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoByName(reg_name); + if (!reg_info) + return 0; + lldb_private::RegisterValue reg_value; + bool success = reg_ctx->ReadRegister(reg_info, reg_value); + if (!success) + return 0; + return reg_value.GetAsUInt16(); +} + +uint32_t read_register_u32_raw(RegisterContext *reg_ctx, + const std::string ®_name) { + const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoByName(reg_name); + if (!reg_info) + return 0; + lldb_private::RegisterValue reg_value; + bool success = reg_ctx->ReadRegister(reg_info, reg_value); + if (!success) + return 0; + return reg_value.GetAsUInt32(); +} + +uint64_t read_register_u64_raw(RegisterContext *reg_ctx, + const std::string ®_name) { + const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoByName(reg_name); + if (!reg_info) + return 0; + lldb_private::RegisterValue reg_value; + bool success = reg_ctx->ReadRegister(reg_info, reg_value); + if (!success) + return 0; + return reg_value.GetAsUInt64(); +} + +llvm::support::ulittle16_t read_register_u16(RegisterContext *reg_ctx, + const std::string ®_name) { + return static_cast<llvm::support::ulittle16_t>( + read_register_u16_raw(reg_ctx, reg_name)); +} + +llvm::support::ulittle32_t read_register_u32(RegisterContext *reg_ctx, + const std::string ®_name) { + return static_cast<llvm::support::ulittle32_t>( + read_register_u32_raw(reg_ctx, reg_name)); +} + +llvm::support::ulittle64_t read_register_u64(RegisterContext *reg_ctx, + const std::string ®_name) { + return static_cast<llvm::support::ulittle64_t>( + read_register_u64_raw(reg_ctx, reg_name)); +} + +lldb_private::minidump::MinidumpContext_x86_64 +GetThreadContext_64(RegisterContext *reg_ctx) { + lldb_private::minidump::MinidumpContext_x86_64 thread_context; + thread_context.context_flags = static_cast<uint32_t>( + lldb_private::minidump::MinidumpContext_x86_64_Flags::x86_64_Flag | + lldb_private::minidump::MinidumpContext_x86_64_Flags::Control | + lldb_private::minidump::MinidumpContext_x86_64_Flags::Segments | + lldb_private::minidump::MinidumpContext_x86_64_Flags::Integer); + thread_context.rax = read_register_u64(reg_ctx, "rax"); + thread_context.rbx = read_register_u64(reg_ctx, "rbx"); + thread_context.rcx = read_register_u64(reg_ctx, "rcx"); + thread_context.rdx = read_register_u64(reg_ctx, "rdx"); + thread_context.rdi = read_register_u64(reg_ctx, "rdi"); + thread_context.rsi = read_register_u64(reg_ctx, "rsi"); + thread_context.rbp = read_register_u64(reg_ctx, "rbp"); + thread_context.rsp = read_register_u64(reg_ctx, "rsp"); + thread_context.r8 = read_register_u64(reg_ctx, "r8"); + thread_context.r9 = read_register_u64(reg_ctx, "r9"); + thread_context.r10 = read_register_u64(reg_ctx, "r10"); + thread_context.r11 = read_register_u64(reg_ctx, "r11"); + thread_context.r12 = read_register_u64(reg_ctx, "r12"); + thread_context.r13 = read_register_u64(reg_ctx, "r13"); + thread_context.r14 = read_register_u64(reg_ctx, "r14"); + thread_context.r15 = read_register_u64(reg_ctx, "r15"); + thread_context.rip = read_register_u64(reg_ctx, "rip"); + thread_context.eflags = read_register_u32(reg_ctx, "rflags"); + thread_context.cs = read_register_u16(reg_ctx, "cs"); + thread_context.fs = read_register_u16(reg_ctx, "fs"); + thread_context.gs = read_register_u16(reg_ctx, "gs"); + thread_context.ss = read_register_u16(reg_ctx, "ss"); + thread_context.ds = read_register_u16(reg_ctx, "ds"); + return thread_context; +} + +// Function returns start and size of the memory region that contains +// memory location pointed to by the current stack pointer. +llvm::Expected<std::pair<addr_t, addr_t>> +findStackHelper(const lldb::ProcessSP &process_sp, uint64_t rsp) { + MemoryRegionInfo range_info; + Status error = process_sp->GetMemoryRegionInfo(rsp, range_info); + // Skip failed memory region requests or any regions with no permissions. + if (error.Fail() || range_info.GetLLDBPermissions() == 0) + return llvm::createStringError( + std::errc::not_supported, + "unable to load stack segment of the process"); + + const addr_t addr = range_info.GetRange().GetRangeBase(); + const addr_t size = range_info.GetRange().GetByteSize(); + + if (size == 0) + return llvm::createStringError(std::errc::not_supported, + "stack segment of the process is empty"); + + return std::make_pair(addr, size); +} + +Status MinidumpFileBuilder::AddThreadList(const lldb::ProcessSP &process_sp) { + constexpr size_t minidump_thread_size = sizeof(llvm::minidump::Thread); + lldb_private::ThreadList thread_list = process_sp->GetThreadList(); + + // size of the entire thread stream consists of: + // number of threads and threads array + size_t thread_stream_size = sizeof(llvm::support::ulittle32_t) + + thread_list.GetSize() * minidump_thread_size; + // save for the ability to set up RVA + size_t size_before = GetCurrentDataEndOffset(); + + AddDirectory(StreamType::ThreadList, thread_stream_size); + + llvm::support::ulittle32_t thread_count = + static_cast<llvm::support::ulittle32_t>(thread_list.GetSize()); + m_data.AppendData(&thread_count, sizeof(llvm::support::ulittle32_t)); + + DataBufferHeap helper_data; + + const uint32_t num_threads = thread_list.GetSize(); + + for (uint32_t thread_idx = 0; thread_idx < num_threads; ++thread_idx) { + ThreadSP thread_sp(thread_list.GetThreadAtIndex(thread_idx)); + RegisterContextSP reg_ctx_sp(thread_sp->GetRegisterContext()); + Status error; + + if (!reg_ctx_sp) { + error.SetErrorString("Unable to get the register context."); + return error; + } + RegisterContext *reg_ctx = reg_ctx_sp.get(); + auto thread_context = GetThreadContext_64(reg_ctx); + uint64_t rsp = read_register_u64_raw(reg_ctx, "rsp"); + auto expected_address_range = findStackHelper(process_sp, rsp); + + if (!expected_address_range) { + error.SetErrorString("Unable to get the stack address."); + return error; + } + + std::pair<uint64_t, uint64_t> range = std::move(*expected_address_range); + uint64_t addr = range.first; + uint64_t size = range.second; + + auto data_up = std::make_unique<DataBufferHeap>(size, 0); + const size_t stack_bytes_read = + process_sp->ReadMemory(addr, data_up->GetBytes(), size, error); + + if (error.Fail()) + return error; + + LocationDescriptor stack_memory; + stack_memory.DataSize = + static_cast<llvm::support::ulittle32_t>(stack_bytes_read); + stack_memory.RVA = static_cast<llvm::support::ulittle32_t>( + size_before + thread_stream_size + helper_data.GetByteSize()); + + MemoryDescriptor stack; + stack.StartOfMemoryRange = static_cast<llvm::support::ulittle64_t>(addr); + stack.Memory = stack_memory; + + helper_data.AppendData(data_up->GetBytes(), stack_bytes_read); + + LocationDescriptor thread_context_memory_locator; + thread_context_memory_locator.DataSize = + static_cast<llvm::support::ulittle32_t>(sizeof(thread_context)); + thread_context_memory_locator.RVA = static_cast<llvm::support::ulittle32_t>( + size_before + thread_stream_size + helper_data.GetByteSize()); + + helper_data.AppendData( + &thread_context, + sizeof(lldb_private::minidump::MinidumpContext_x86_64)); + + llvm::minidump::Thread t; + t.ThreadId = static_cast<llvm::support::ulittle32_t>(thread_sp->GetID()); + t.SuspendCount = static_cast<llvm::support::ulittle32_t>( + (thread_sp->GetState() == StateType::eStateSuspended) ? 1 : 0); + t.PriorityClass = static_cast<llvm::support::ulittle32_t>(0); + t.Priority = static_cast<llvm::support::ulittle32_t>(0); + t.EnvironmentBlock = static_cast<llvm::support::ulittle64_t>(0); + t.Stack = stack, t.Context = thread_context_memory_locator; + + m_data.AppendData(&t, sizeof(llvm::minidump::Thread)); + } + + m_data.AppendData(helper_data.GetBytes(), helper_data.GetByteSize()); + return Status(); +} + +Status MinidumpFileBuilder::AddException(const lldb::ProcessSP &process_sp) { + Status error; + lldb_private::ThreadList thread_list = process_sp->GetThreadList(); + + const uint32_t num_threads = thread_list.GetSize(); + uint32_t stop_reason_thread_idx = 0; + for (stop_reason_thread_idx = 0; stop_reason_thread_idx < num_threads; + ++stop_reason_thread_idx) { + ThreadSP thread_sp(thread_list.GetThreadAtIndex(stop_reason_thread_idx)); + StopInfoSP stop_info_sp = thread_sp->GetStopInfo(); + + if (stop_info_sp && stop_info_sp->IsValid()) + break; + } + + if (stop_reason_thread_idx == num_threads) { + error.SetErrorString("No stop reason thread found."); + return error; + } + + constexpr size_t minidump_exception_size = + sizeof(llvm::minidump::ExceptionStream); + AddDirectory(StreamType::Exception, minidump_exception_size); + size_t size_before = GetCurrentDataEndOffset(); + + ThreadSP thread_sp(thread_list.GetThreadAtIndex(stop_reason_thread_idx)); + RegisterContextSP reg_ctx_sp(thread_sp->GetRegisterContext()); + RegisterContext *reg_ctx = reg_ctx_sp.get(); + auto thread_context = GetThreadContext_64(reg_ctx); + StopInfoSP stop_info_sp = thread_sp->GetStopInfo(); + + DataBufferHeap helper_data; + + LocationDescriptor thread_context_memory_locator; + thread_context_memory_locator.DataSize = + static_cast<llvm::support::ulittle32_t>(sizeof(thread_context)); + thread_context_memory_locator.RVA = static_cast<llvm::support::ulittle32_t>( + size_before + minidump_exception_size + helper_data.GetByteSize()); + + helper_data.AppendData( + &thread_context, sizeof(lldb_private::minidump::MinidumpContext_x86_64)); + + Exception exp_record; + exp_record.ExceptionCode = + static_cast<llvm::support::ulittle32_t>(stop_info_sp->GetValue()); + exp_record.ExceptionFlags = static_cast<llvm::support::ulittle32_t>(0); + exp_record.ExceptionRecord = static_cast<llvm::support::ulittle64_t>(0); + exp_record.ExceptionAddress = read_register_u64(reg_ctx, "rip"); + exp_record.NumberParameters = static_cast<llvm::support::ulittle32_t>(0); + exp_record.UnusedAlignment = static_cast<llvm::support::ulittle32_t>(0); + // exp_record.ExceptionInformation; + + ExceptionStream exp_stream; + exp_stream.ThreadId = + static_cast<llvm::support::ulittle32_t>(thread_sp->GetID()); + exp_stream.UnusedAlignment = static_cast<llvm::support::ulittle32_t>(0); + exp_stream.ExceptionRecord = exp_record; + exp_stream.ThreadContext = thread_context_memory_locator; + + m_data.AppendData(&exp_stream, minidump_exception_size); + m_data.AppendData(helper_data.GetBytes(), helper_data.GetByteSize()); + return error; +} + +lldb_private::Status +MinidumpFileBuilder::AddMemoryList(const lldb::ProcessSP &process_sp) { + Status error; + + if (error.Fail()) { + error.SetErrorString("Process doesn't support getting memory region info."); + return error; + } + + // Get interesting addresses + std::vector<size_t> interesting_addresses; + auto thread_list = process_sp->GetThreadList(); + for (size_t i = 0; i < thread_list.GetSize(); ++i) { + ThreadSP thread_sp(thread_list.GetThreadAtIndex(i)); + RegisterContextSP reg_ctx_sp(thread_sp->GetRegisterContext()); + RegisterContext *reg_ctx = reg_ctx_sp.get(); + + interesting_addresses.push_back(read_register_u64(reg_ctx, "rsp")); + interesting_addresses.push_back(read_register_u64(reg_ctx, "rip")); + } + + DataBufferHeap helper_data; + std::vector<MemoryDescriptor> mem_descriptors; + + std::set<addr_t> visited_region_base_addresses; + for (size_t interesting_address : interesting_addresses) { + MemoryRegionInfo range_info; + error = process_sp->GetMemoryRegionInfo(interesting_address, range_info); + // Skip failed memory region requests or any regions with no permissions. + if (error.Fail() || range_info.GetLLDBPermissions() == 0) + continue; + const addr_t addr = range_info.GetRange().GetRangeBase(); + // Skip any regions we have already saved out. + if (visited_region_base_addresses.insert(addr).second == false) + continue; + const addr_t size = range_info.GetRange().GetByteSize(); + if (size == 0) + continue; + auto data_up = std::make_unique<DataBufferHeap>(size, 0); + const size_t bytes_read = + process_sp->ReadMemory(addr, data_up->GetBytes(), size, error); + if (bytes_read == 0) + continue; + // We have a good memory region with valid bytes to store. + LocationDescriptor memory_dump; + memory_dump.DataSize = static_cast<llvm::support::ulittle32_t>(bytes_read); + memory_dump.RVA = + static_cast<llvm::support::ulittle32_t>(GetCurrentDataEndOffset()); + MemoryDescriptor memory_desc; + memory_desc.StartOfMemoryRange = + static_cast<llvm::support::ulittle64_t>(addr); + memory_desc.Memory = memory_dump; + mem_descriptors.push_back(memory_desc); + m_data.AppendData(data_up->GetBytes(), bytes_read); + } + + AddDirectory(StreamType::MemoryList, + sizeof(llvm::support::ulittle32_t) + + mem_descriptors.size() * + sizeof(llvm::minidump::MemoryDescriptor)); + llvm::support::ulittle32_t memory_ranges_num(mem_descriptors.size()); + + m_data.AppendData(&memory_ranges_num, sizeof(llvm::support::ulittle32_t)); + for (auto memory_descriptor : mem_descriptors) { + m_data.AppendData(&memory_descriptor, + sizeof(llvm::minidump::MemoryDescriptor)); + } + + return error; +} + +void MinidumpFileBuilder::AddMiscInfo(const lldb::ProcessSP &process_sp) { + AddDirectory(StreamType::MiscInfo, + sizeof(lldb_private::minidump::MinidumpMiscInfo)); + + lldb_private::minidump::MinidumpMiscInfo misc_info; + misc_info.size = static_cast<llvm::support::ulittle32_t>( + sizeof(lldb_private::minidump::MinidumpMiscInfo)); + // Default set flags1 to 0, in case that we will not be able to + // get any information + misc_info.flags1 = static_cast<llvm::support::ulittle32_t>(0); + + lldb_private::ProcessInstanceInfo process_info; + process_sp->GetProcessInfo(process_info); + if (process_info.ProcessIDIsValid()) { + // Set flags1 to reflect that PID is filled in + misc_info.flags1 = + static_cast<llvm::support::ulittle32_t>(static_cast<uint32_t>( + lldb_private::minidump::MinidumpMiscInfoFlags::ProcessID)); + misc_info.process_id = + static_cast<llvm::support::ulittle32_t>(process_info.GetProcessID()); + } + + m_data.AppendData(&misc_info, + sizeof(lldb_private::minidump::MinidumpMiscInfo)); +} + +std::unique_ptr<llvm::MemoryBuffer> +getFileStreamHelper(const std::string &path) { + auto maybe_stream = llvm::MemoryBuffer::getFileAsStream(path); + if (!maybe_stream) + return nullptr; + return std::move(maybe_stream.get()); +} + +void MinidumpFileBuilder::AddLinuxFileStreams( + const lldb::ProcessSP &process_sp) { + std::vector<std::pair<StreamType, std::string>> files_with_stream_types = { + {StreamType::LinuxCPUInfo, "/proc/cpuinfo"}, + {StreamType::LinuxLSBRelease, "/etc/lsb-release"}, + }; + + lldb_private::ProcessInstanceInfo process_info; + process_sp->GetProcessInfo(process_info); + if (process_info.ProcessIDIsValid()) { + lldb::pid_t pid = process_info.GetProcessID(); + std::string pid_str = std::to_string(pid); + files_with_stream_types.push_back( + {StreamType::LinuxProcStatus, "/proc/" + pid_str + "/status"}); + files_with_stream_types.push_back( + {StreamType::LinuxCMDLine, "/proc/" + pid_str + "/cmdline"}); + files_with_stream_types.push_back( + {StreamType::LinuxEnviron, "/proc/" + pid_str + "/environ"}); + files_with_stream_types.push_back( + {StreamType::LinuxAuxv, "/proc/" + pid_str + "/auxv"}); + files_with_stream_types.push_back( + {StreamType::LinuxMaps, "/proc/" + pid_str + "/maps"}); + files_with_stream_types.push_back( + {StreamType::LinuxProcStat, "/proc/" + pid_str + "/stat"}); + files_with_stream_types.push_back( + {StreamType::LinuxProcFD, "/proc/" + pid_str + "/fd"}); + } + + for (const auto &entry : files_with_stream_types) { + StreamType stream = entry.first; + std::string path = entry.second; + auto memory_buffer = getFileStreamHelper(path); + + if (memory_buffer) { + size_t size = memory_buffer->getBufferSize(); + if (size == 0) + continue; + AddDirectory(stream, size); + m_data.AppendData(memory_buffer->getBufferStart(), size); + } + } +} + +Status MinidumpFileBuilder::Dump(lldb::FileUP &core_file) const { + constexpr size_t header_size = sizeof(llvm::minidump::Header); + constexpr size_t directory_size = sizeof(llvm::minidump::Directory); + + // write header + llvm::minidump::Header header; + header.Signature = static_cast<llvm::support::ulittle32_t>( + llvm::minidump::Header::MagicSignature); + header.Version = static_cast<llvm::support::ulittle32_t>( + llvm::minidump::Header::MagicVersion); + header.NumberOfStreams = + static_cast<llvm::support::ulittle32_t>(GetDirectoriesNum()); + header.StreamDirectoryRVA = + static_cast<llvm::support::ulittle32_t>(GetCurrentDataEndOffset()); + header.Checksum = static_cast<llvm::support::ulittle32_t>( + 0u), // not used in most of the writers + header.TimeDateStamp = + static_cast<llvm::support::ulittle32_t>(std::time(0)); + header.Flags = + static_cast<llvm::support::ulittle64_t>(0u); // minidump normal flag + + Status error; + size_t bytes_written; + + bytes_written = header_size; + error = core_file->Write(&header, bytes_written); + if (error.Fail() || bytes_written != header_size) { + if (bytes_written != header_size) + error.SetErrorStringWithFormat( + "unable to write the header (written %zd/%zd)", bytes_written, + header_size); + return error; + } + + // write data + bytes_written = m_data.GetByteSize(); + error = core_file->Write(m_data.GetBytes(), bytes_written); + if (error.Fail() || bytes_written != m_data.GetByteSize()) { + if (bytes_written != m_data.GetByteSize()) + error.SetErrorStringWithFormat( + "unable to write the data (written %zd/%" PRIu64 ")", bytes_written, + m_data.GetByteSize()); + return error; + } + + // write directories + for (const Directory &dir : m_directories) { + bytes_written = directory_size; + error = core_file->Write(&dir, bytes_written); + if (error.Fail() || bytes_written != directory_size) { + if (bytes_written != directory_size) + error.SetErrorStringWithFormat( + "unable to write the directory (written %zd/%zd)", bytes_written, + directory_size); + return error; + } + } + + return error; +} + +size_t MinidumpFileBuilder::GetDirectoriesNum() const { + return m_directories.size(); +} + +size_t MinidumpFileBuilder::GetCurrentDataEndOffset() const { + return sizeof(llvm::minidump::Header) + m_data.GetByteSize(); +} diff --git a/contrib/llvm-project/lldb/source/Plugins/ObjectFile/Minidump/MinidumpFileBuilder.h b/contrib/llvm-project/lldb/source/Plugins/ObjectFile/Minidump/MinidumpFileBuilder.h new file mode 100644 index 000000000000..f4017fb66384 --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/ObjectFile/Minidump/MinidumpFileBuilder.h @@ -0,0 +1,92 @@ +//===-- MinidumpFileBuilder.h ---------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +/// \file +/// Structure holding data neccessary for minidump file creation. +/// +/// The class MinidumpFileWriter is used to hold the data that will eventually +/// be dumped to the file. +//===----------------------------------------------------------------------===// + +#ifndef LLDB_SOURCE_PLUGINS_OBJECTFILE_MINIDUMP_MINIDUMPFILEBUILDER_H +#define LLDB_SOURCE_PLUGINS_OBJECTFILE_MINIDUMP_MINIDUMPFILEBUILDER_H + +#include <cstddef> + +#include "lldb/Target/Target.h" +#include "lldb/Utility/DataBufferHeap.h" +#include "lldb/Utility/Status.h" + +#include "llvm/Object/Minidump.h" + +// Write std::string to minidump in the UTF16 format(with null termination char) +// with the size(without null termination char) preceding the UTF16 string. +// Empty strings are also printed with zero length and just null termination +// char. +lldb_private::Status WriteString(const std::string &to_write, + lldb_private::DataBufferHeap *buffer); + +/// \class MinidumpFileBuilder +/// Minidump writer for Linux +/// +/// This class provides a Minidump writer that is able to +/// snapshot the current process state. For the whole time, it stores all +/// the data on heap. +class MinidumpFileBuilder { +public: + MinidumpFileBuilder() = default; + + MinidumpFileBuilder(const MinidumpFileBuilder &) = delete; + MinidumpFileBuilder &operator=(const MinidumpFileBuilder &) = delete; + + MinidumpFileBuilder(MinidumpFileBuilder &&other) = default; + MinidumpFileBuilder &operator=(MinidumpFileBuilder &&other) = default; + + ~MinidumpFileBuilder() = default; + + // Add SystemInfo stream, used for storing the most basic information + // about the system, platform etc... + lldb_private::Status AddSystemInfo(const llvm::Triple &target_triple); + // Add ModuleList stream, containing information about all loaded modules + // at the time of saving minidump. + lldb_private::Status AddModuleList(lldb_private::Target &target); + // Add ThreadList stream, containing information about all threads running + // at the moment of core saving. Contains information about thread + // contexts. + lldb_private::Status AddThreadList(const lldb::ProcessSP &process_sp); + // Add Exception stream, this contains information about the exception + // that stopped the process. In case no thread made exception it return + // failed status. + lldb_private::Status AddException(const lldb::ProcessSP &process_sp); + // Add MemoryList stream, containing dumps of important memory segments + lldb_private::Status AddMemoryList(const lldb::ProcessSP &process_sp); + // Add MiscInfo stream, mainly providing ProcessId + void AddMiscInfo(const lldb::ProcessSP &process_sp); + // Add informative files about a Linux process + void AddLinuxFileStreams(const lldb::ProcessSP &process_sp); + // Dump the prepared data into file. In case of the failure data are + // intact. + lldb_private::Status Dump(lldb::FileUP &core_file) const; + // Returns the current number of directories(streams) that have been so far + // created. This number of directories will be dumped when calling Dump() + size_t GetDirectoriesNum() const; + +private: + // Add directory of StreamType pointing to the current end of the prepared + // file with the specified size. + void AddDirectory(llvm::minidump::StreamType type, size_t stream_size); + size_t GetCurrentDataEndOffset() const; + + // Stores directories to later put them at the end of minidump file + std::vector<llvm::minidump::Directory> m_directories; + // Main data buffer consisting of data without the minidump header and + // directories + lldb_private::DataBufferHeap m_data; +}; + +#endif // LLDB_SOURCE_PLUGINS_OBJECTFILE_MINIDUMP_MINIDUMPFILEBUILDER_H diff --git a/contrib/llvm-project/lldb/source/Plugins/ObjectFile/Minidump/ObjectFileMinidump.cpp b/contrib/llvm-project/lldb/source/Plugins/ObjectFile/Minidump/ObjectFileMinidump.cpp new file mode 100644 index 000000000000..715ccd311dee --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/ObjectFile/Minidump/ObjectFileMinidump.cpp @@ -0,0 +1,114 @@ +//===-- ObjectFileMinidump.cpp --------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "ObjectFileMinidump.h" + +#include "MinidumpFileBuilder.h" + +#include "lldb/Core/ModuleSpec.h" +#include "lldb/Core/PluginManager.h" +#include "lldb/Core/Section.h" +#include "lldb/Target/Process.h" + +#include "llvm/Support/FileSystem.h" + +using namespace lldb; +using namespace lldb_private; + +LLDB_PLUGIN_DEFINE(ObjectFileMinidump) + +void ObjectFileMinidump::Initialize() { + PluginManager::RegisterPlugin( + GetPluginNameStatic(), GetPluginDescriptionStatic(), CreateInstance, + CreateMemoryInstance, GetModuleSpecifications, SaveCore); +} + +void ObjectFileMinidump::Terminate() { + PluginManager::UnregisterPlugin(CreateInstance); +} + +ObjectFile *ObjectFileMinidump::CreateInstance( + const lldb::ModuleSP &module_sp, lldb::DataBufferSP &data_sp, + lldb::offset_t data_offset, const lldb_private::FileSpec *file, + lldb::offset_t offset, lldb::offset_t length) { + return nullptr; +} + +ObjectFile *ObjectFileMinidump::CreateMemoryInstance( + const lldb::ModuleSP &module_sp, DataBufferSP &data_sp, + const ProcessSP &process_sp, lldb::addr_t header_addr) { + return nullptr; +} + +size_t ObjectFileMinidump::GetModuleSpecifications( + const lldb_private::FileSpec &file, lldb::DataBufferSP &data_sp, + lldb::offset_t data_offset, lldb::offset_t file_offset, + lldb::offset_t length, lldb_private::ModuleSpecList &specs) { + specs.Clear(); + return 0; +} + +bool ObjectFileMinidump::SaveCore(const lldb::ProcessSP &process_sp, + const lldb_private::FileSpec &outfile, + lldb::SaveCoreStyle &core_style, + lldb_private::Status &error) { + if (core_style != SaveCoreStyle::eSaveCoreStackOnly) { + error.SetErrorString("Only stack minidumps supported yet."); + return false; + } + + if (!process_sp) + return false; + + MinidumpFileBuilder builder; + + Target &target = process_sp->GetTarget(); + + error = builder.AddSystemInfo(target.GetArchitecture().GetTriple()); + if (error.Fail()) + return false; + + error = builder.AddModuleList(target); + if (error.Fail()) + return false; + + builder.AddMiscInfo(process_sp); + + if (target.GetArchitecture().GetMachine() == llvm::Triple::ArchType::x86_64) { + error = builder.AddThreadList(process_sp); + if (error.Fail()) + return false; + + error = builder.AddException(process_sp); + if (error.Fail()) + return false; + + error = builder.AddMemoryList(process_sp); + if (error.Fail()) + return false; + } + + if (target.GetArchitecture().GetTriple().getOS() == + llvm::Triple::OSType::Linux) { + builder.AddLinuxFileStreams(process_sp); + } + + llvm::Expected<lldb::FileUP> maybe_core_file = FileSystem::Instance().Open( + outfile, File::eOpenOptionWriteOnly | File::eOpenOptionCanCreate); + if (!maybe_core_file) { + error = maybe_core_file.takeError(); + return false; + } + lldb::FileUP core_file = std::move(maybe_core_file.get()); + + error = builder.Dump(core_file); + if (error.Fail()) + return false; + + return true; +} diff --git a/contrib/llvm-project/lldb/source/Plugins/ObjectFile/Minidump/ObjectFileMinidump.h b/contrib/llvm-project/lldb/source/Plugins/ObjectFile/Minidump/ObjectFileMinidump.h new file mode 100644 index 000000000000..3e4d55dc6c8c --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/ObjectFile/Minidump/ObjectFileMinidump.h @@ -0,0 +1,66 @@ +//===-- ObjectFileMinidump.h ---------------------------------- -*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +/// \file +/// Placeholder plugin for the save core functionality. +/// +/// ObjectFileMinidump is created only to be able to save minidump core files +/// from existing processes with the ObjectFileMinidump::SaveCore function. +/// Minidump files are not ObjectFile objects, but they are core files and +/// currently LLDB's ObjectFile plug-ins handle emitting core files. If the +/// core file saving ever moves into a new plug-in type within LLDB, this code +/// should move as well, but for now this is the best place architecturally. +//===----------------------------------------------------------------------===// + +#ifndef LLDB_SOURCE_PLUGINS_OBJECTFILE_MINIDUMP_OBJECTFILEMINIDUMP_H +#define LLDB_SOURCE_PLUGINS_OBJECTFILE_MINIDUMP_OBJECTFILEMINIDUMP_H + +#include "lldb/Symbol/ObjectFile.h" +#include "lldb/Utility/ArchSpec.h" + +class ObjectFileMinidump : public lldb_private::PluginInterface { +public: + // Static Functions + static void Initialize(); + static void Terminate(); + + static llvm::StringRef GetPluginNameStatic() { return "minidump"; } + static const char *GetPluginDescriptionStatic() { + return "Minidump object file."; + } + + // PluginInterface protocol + llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); } + + static lldb_private::ObjectFile * + CreateInstance(const lldb::ModuleSP &module_sp, lldb::DataBufferSP &data_sp, + lldb::offset_t data_offset, const lldb_private::FileSpec *file, + lldb::offset_t offset, lldb::offset_t length); + + static lldb_private::ObjectFile *CreateMemoryInstance( + const lldb::ModuleSP &module_sp, lldb::DataBufferSP &data_sp, + const lldb::ProcessSP &process_sp, lldb::addr_t header_addr); + + static size_t GetModuleSpecifications(const lldb_private::FileSpec &file, + lldb::DataBufferSP &data_sp, + lldb::offset_t data_offset, + lldb::offset_t file_offset, + lldb::offset_t length, + lldb_private::ModuleSpecList &specs); + + // Saves dump in Minidump file format + static bool SaveCore(const lldb::ProcessSP &process_sp, + const lldb_private::FileSpec &outfile, + lldb::SaveCoreStyle &core_style, + lldb_private::Status &error); + +private: + ObjectFileMinidump() = default; +}; + +#endif // LLDB_SOURCE_PLUGINS_OBJECTFILE_MINIDUMP_OBJECTFILEMINIDUMP_H diff --git a/contrib/llvm-project/lldb/source/Plugins/ObjectFile/PDB/ObjectFilePDB.cpp b/contrib/llvm-project/lldb/source/Plugins/ObjectFile/PDB/ObjectFilePDB.cpp index cb7bbeeca054..b63cd8e70899 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ObjectFile/PDB/ObjectFilePDB.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/ObjectFile/PDB/ObjectFilePDB.cpp @@ -46,11 +46,6 @@ void ObjectFilePDB::Terminate() { PluginManager::UnregisterPlugin(CreateInstance); } -ConstString ObjectFilePDB::GetPluginNameStatic() { - static ConstString g_name("pdb"); - return g_name; -} - ArchSpec ObjectFilePDB::GetArchitecture() { auto dbi_stream = m_file_up->getPDBDbiStream(); if (!dbi_stream) { diff --git a/contrib/llvm-project/lldb/source/Plugins/ObjectFile/PDB/ObjectFilePDB.h b/contrib/llvm-project/lldb/source/Plugins/ObjectFile/PDB/ObjectFilePDB.h index 19dd46b31406..36e71e21332f 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ObjectFile/PDB/ObjectFilePDB.h +++ b/contrib/llvm-project/lldb/source/Plugins/ObjectFile/PDB/ObjectFilePDB.h @@ -22,7 +22,7 @@ public: static void Initialize(); static void Terminate(); - static ConstString GetPluginNameStatic(); + static llvm::StringRef GetPluginNameStatic() { return "pdb"; } static const char *GetPluginDescriptionStatic() { return "PDB object file reader."; } @@ -48,9 +48,7 @@ public: ModuleSpecList &specs); // PluginInterface protocol - ConstString GetPluginName() override { return GetPluginNameStatic(); } - - uint32_t GetPluginVersion() override { return 1; } + llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); } // LLVM RTTI support static char ID; diff --git a/contrib/llvm-project/lldb/source/Plugins/ObjectFile/wasm/ObjectFileWasm.cpp b/contrib/llvm-project/lldb/source/Plugins/ObjectFile/wasm/ObjectFileWasm.cpp index 5272da9ab33a..0e6329885528 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ObjectFile/wasm/ObjectFileWasm.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/ObjectFile/wasm/ObjectFileWasm.cpp @@ -86,11 +86,6 @@ void ObjectFileWasm::Terminate() { PluginManager::UnregisterPlugin(CreateInstance); } -ConstString ObjectFileWasm::GetPluginNameStatic() { - static ConstString g_name("wasm"); - return g_name; -} - ObjectFile * ObjectFileWasm::CreateInstance(const ModuleSP &module_sp, DataBufferSP &data_sp, offset_t data_offset, const FileSpec *file, diff --git a/contrib/llvm-project/lldb/source/Plugins/ObjectFile/wasm/ObjectFileWasm.h b/contrib/llvm-project/lldb/source/Plugins/ObjectFile/wasm/ObjectFileWasm.h index b6e906a7b15f..44939b6d4ea0 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ObjectFile/wasm/ObjectFileWasm.h +++ b/contrib/llvm-project/lldb/source/Plugins/ObjectFile/wasm/ObjectFileWasm.h @@ -24,7 +24,7 @@ public: static void Initialize(); static void Terminate(); - static ConstString GetPluginNameStatic(); + static llvm::StringRef GetPluginNameStatic() { return "wasm"; } static const char *GetPluginDescriptionStatic() { return "WebAssembly object file reader."; } @@ -48,8 +48,7 @@ public: /// PluginInterface protocol. /// \{ - ConstString GetPluginName() override { return GetPluginNameStatic(); } - uint32_t GetPluginVersion() override { return 1; } + llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); } /// \} /// LLVM RTTI support diff --git a/contrib/llvm-project/lldb/source/Plugins/OperatingSystem/Python/OperatingSystemPython.cpp b/contrib/llvm-project/lldb/source/Plugins/OperatingSystem/Python/OperatingSystemPython.cpp index 730c88f96e13..7d14f02e68f7 100644 --- a/contrib/llvm-project/lldb/source/Plugins/OperatingSystem/Python/OperatingSystemPython.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/OperatingSystem/Python/OperatingSystemPython.cpp @@ -12,7 +12,6 @@ #include "OperatingSystemPython.h" -#include "Plugins/Process/Utility/DynamicRegisterInfo.h" #include "Plugins/Process/Utility/RegisterContextDummy.h" #include "Plugins/Process/Utility/RegisterContextMemory.h" #include "Plugins/Process/Utility/ThreadMemory.h" @@ -66,12 +65,7 @@ OperatingSystem *OperatingSystemPython::CreateInstance(Process *process, return nullptr; } -ConstString OperatingSystemPython::GetPluginNameStatic() { - static ConstString g_name("python"); - return g_name; -} - -const char *OperatingSystemPython::GetPluginDescriptionStatic() { +llvm::StringRef OperatingSystemPython::GetPluginDescriptionStatic() { return "Operating system plug-in that gathers OS information from a python " "class that implements the necessary OperatingSystem functionality."; } @@ -141,13 +135,6 @@ DynamicRegisterInfo *OperatingSystemPython::GetDynamicRegisterInfo() { return m_register_info_up.get(); } -// PluginInterface protocol -ConstString OperatingSystemPython::GetPluginName() { - return GetPluginNameStatic(); -} - -uint32_t OperatingSystemPython::GetPluginVersion() { return 1; } - bool OperatingSystemPython::UpdateThreadList(ThreadList &old_thread_list, ThreadList &core_thread_list, ThreadList &new_thread_list) { diff --git a/contrib/llvm-project/lldb/source/Plugins/OperatingSystem/Python/OperatingSystemPython.h b/contrib/llvm-project/lldb/source/Plugins/OperatingSystem/Python/OperatingSystemPython.h index 4a594cf29a08..7800cf03af8e 100644 --- a/contrib/llvm-project/lldb/source/Plugins/OperatingSystem/Python/OperatingSystemPython.h +++ b/contrib/llvm-project/lldb/source/Plugins/OperatingSystem/Python/OperatingSystemPython.h @@ -13,11 +13,10 @@ #if LLDB_ENABLE_PYTHON +#include "lldb/Target/DynamicRegisterInfo.h" #include "lldb/Target/OperatingSystem.h" #include "lldb/Utility/StructuredData.h" -class DynamicRegisterInfo; - namespace lldb_private { class ScriptInterpreter; } @@ -37,14 +36,12 @@ public: static void Terminate(); - static lldb_private::ConstString GetPluginNameStatic(); + static llvm::StringRef GetPluginNameStatic() { return "python"; } - static const char *GetPluginDescriptionStatic(); + static llvm::StringRef GetPluginDescriptionStatic(); // lldb_private::PluginInterface Methods - lldb_private::ConstString GetPluginName() override; - - uint32_t GetPluginVersion() override; + llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); } // lldb_private::OperatingSystem Methods bool UpdateThreadList(lldb_private::ThreadList &old_thread_list, @@ -74,14 +71,14 @@ protected: lldb_private::ThreadList &old_thread_list, std::vector<bool> &core_used_map, bool *did_create_ptr); - DynamicRegisterInfo *GetDynamicRegisterInfo(); + lldb_private::DynamicRegisterInfo *GetDynamicRegisterInfo(); lldb::ValueObjectSP m_thread_list_valobj_sp; - std::unique_ptr<DynamicRegisterInfo> m_register_info_up; + std::unique_ptr<lldb_private::DynamicRegisterInfo> m_register_info_up; lldb_private::ScriptInterpreter *m_interpreter; lldb_private::StructuredData::ObjectSP m_python_object_sp; }; -#endif +#endif // LLDB_ENABLE_PYTHON #endif // liblldb_OperatingSystemPython_h_ diff --git a/contrib/llvm-project/lldb/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.cpp b/contrib/llvm-project/lldb/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.cpp index 7b3d8a375bf6..754d06de7cb9 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.cpp @@ -76,25 +76,10 @@ PlatformSP PlatformFreeBSD::CreateInstance(bool force, const ArchSpec *arch) { return PlatformSP(); } -ConstString PlatformFreeBSD::GetPluginNameStatic(bool is_host) { - if (is_host) { - static ConstString g_host_name(Platform::GetHostPlatformName()); - return g_host_name; - } else { - static ConstString g_remote_name("remote-freebsd"); - return g_remote_name; - } -} - -const char *PlatformFreeBSD::GetPluginDescriptionStatic(bool is_host) { +llvm::StringRef PlatformFreeBSD::GetPluginDescriptionStatic(bool is_host) { if (is_host) return "Local FreeBSD user platform plug-in."; - else - return "Remote FreeBSD user platform plug-in."; -} - -ConstString PlatformFreeBSD::GetPluginName() { - return GetPluginNameStatic(IsHost()); + return "Remote FreeBSD user platform plug-in."; } void PlatformFreeBSD::Initialize() { @@ -126,72 +111,27 @@ void PlatformFreeBSD::Terminate() { /// Default Constructor PlatformFreeBSD::PlatformFreeBSD(bool is_host) : PlatformPOSIX(is_host) // This is the local host platform -{} - -bool PlatformFreeBSD::GetSupportedArchitectureAtIndex(uint32_t idx, - ArchSpec &arch) { - if (IsHost()) { +{ + if (is_host) { ArchSpec hostArch = HostInfo::GetArchitecture(HostInfo::eArchKindDefault); - if (hostArch.GetTriple().isOSFreeBSD()) { - if (idx == 0) { - arch = hostArch; - return arch.IsValid(); - } else if (idx == 1) { - // If the default host architecture is 64-bit, look for a 32-bit - // variant - if (hostArch.IsValid() && hostArch.GetTriple().isArch64Bit()) { - arch = HostInfo::GetArchitecture(HostInfo::eArchKind32); - return arch.IsValid(); - } - } + m_supported_architectures.push_back(hostArch); + if (hostArch.GetTriple().isArch64Bit()) { + m_supported_architectures.push_back( + HostInfo::GetArchitecture(HostInfo::eArchKind32)); } } else { - if (m_remote_platform_sp) - return m_remote_platform_sp->GetSupportedArchitectureAtIndex(idx, arch); - - llvm::Triple triple; - // Set the OS to FreeBSD - triple.setOS(llvm::Triple::FreeBSD); - // Set the architecture - switch (idx) { - case 0: - triple.setArchName("x86_64"); - break; - case 1: - triple.setArchName("i386"); - break; - case 2: - triple.setArchName("aarch64"); - break; - case 3: - triple.setArchName("arm"); - break; - case 4: - triple.setArchName("mips64"); - break; - case 5: - triple.setArchName("mips"); - break; - case 6: - triple.setArchName("ppc64"); - break; - case 7: - triple.setArchName("ppc"); - break; - default: - return false; - } - // Leave the vendor as "llvm::Triple:UnknownVendor" and don't specify the - // vendor by calling triple.SetVendorName("unknown") so that it is a - // "unspecified unknown". This means when someone calls - // triple.GetVendorName() it will return an empty string which indicates - // that the vendor can be set when two architectures are merged - - // Now set the triple into "arch" and return true - arch.SetTriple(triple); - return true; + m_supported_architectures = CreateArchList( + {llvm::Triple::x86_64, llvm::Triple::x86, llvm::Triple::aarch64, + llvm::Triple::arm, llvm::Triple::mips64, llvm::Triple::ppc64, + llvm::Triple::ppc}, + llvm::Triple::FreeBSD); } - return false; +} + +std::vector<ArchSpec> PlatformFreeBSD::GetSupportedArchitectures() { + if (m_remote_platform_sp) + return m_remote_platform_sp->GetSupportedArchitectures(); + return m_supported_architectures; } void PlatformFreeBSD::GetStatus(Stream &strm) { diff --git a/contrib/llvm-project/lldb/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.h b/contrib/llvm-project/lldb/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.h index 4fd10fb1be73..fd37b13de017 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.h +++ b/contrib/llvm-project/lldb/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.h @@ -25,22 +25,24 @@ public: // lldb_private::PluginInterface functions static lldb::PlatformSP CreateInstance(bool force, const ArchSpec *arch); - static ConstString GetPluginNameStatic(bool is_host); - - static const char *GetPluginDescriptionStatic(bool is_host); + static llvm::StringRef GetPluginNameStatic(bool is_host) { + return is_host ? Platform::GetHostPlatformName() : "remote-freebsd"; + } - ConstString GetPluginName() override; + static llvm::StringRef GetPluginDescriptionStatic(bool is_host); - uint32_t GetPluginVersion() override { return 1; } + llvm::StringRef GetPluginName() override { + return GetPluginNameStatic(IsHost()); + } // lldb_private::Platform functions - const char *GetDescription() override { + llvm::StringRef GetDescription() override { return GetPluginDescriptionStatic(IsHost()); } void GetStatus(Stream &strm) override; - bool GetSupportedArchitectureAtIndex(uint32_t idx, ArchSpec &arch) override; + std::vector<ArchSpec> GetSupportedArchitectures() override; bool CanDebugProcess() override; @@ -50,6 +52,8 @@ public: lldb::addr_t length, unsigned prot, unsigned flags, lldb::addr_t fd, lldb::addr_t offset) override; + + std::vector<ArchSpec> m_supported_architectures; }; } // namespace platform_freebsd diff --git a/contrib/llvm-project/lldb/source/Plugins/Platform/NetBSD/PlatformNetBSD.cpp b/contrib/llvm-project/lldb/source/Plugins/Platform/NetBSD/PlatformNetBSD.cpp index e3682b44e141..552b3890615c 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Platform/NetBSD/PlatformNetBSD.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Platform/NetBSD/PlatformNetBSD.cpp @@ -65,25 +65,10 @@ PlatformSP PlatformNetBSD::CreateInstance(bool force, const ArchSpec *arch) { return PlatformSP(); } -ConstString PlatformNetBSD::GetPluginNameStatic(bool is_host) { - if (is_host) { - static ConstString g_host_name(Platform::GetHostPlatformName()); - return g_host_name; - } else { - static ConstString g_remote_name("remote-netbsd"); - return g_remote_name; - } -} - -const char *PlatformNetBSD::GetPluginDescriptionStatic(bool is_host) { +llvm::StringRef PlatformNetBSD::GetPluginDescriptionStatic(bool is_host) { if (is_host) return "Local NetBSD user platform plug-in."; - else - return "Remote NetBSD user platform plug-in."; -} - -ConstString PlatformNetBSD::GetPluginName() { - return GetPluginNameStatic(IsHost()); + return "Remote NetBSD user platform plug-in."; } void PlatformNetBSD::Initialize() { @@ -115,54 +100,24 @@ void PlatformNetBSD::Terminate() { /// Default Constructor PlatformNetBSD::PlatformNetBSD(bool is_host) : PlatformPOSIX(is_host) // This is the local host platform -{} - -bool PlatformNetBSD::GetSupportedArchitectureAtIndex(uint32_t idx, - ArchSpec &arch) { - if (IsHost()) { +{ + if (is_host) { ArchSpec hostArch = HostInfo::GetArchitecture(HostInfo::eArchKindDefault); - if (hostArch.GetTriple().isOSNetBSD()) { - if (idx == 0) { - arch = hostArch; - return arch.IsValid(); - } else if (idx == 1) { - // If the default host architecture is 64-bit, look for a 32-bit - // variant - if (hostArch.IsValid() && hostArch.GetTriple().isArch64Bit()) { - arch = HostInfo::GetArchitecture(HostInfo::eArchKind32); - return arch.IsValid(); - } - } + m_supported_architectures.push_back(hostArch); + if (hostArch.GetTriple().isArch64Bit()) { + m_supported_architectures.push_back( + HostInfo::GetArchitecture(HostInfo::eArchKind32)); } } else { - if (m_remote_platform_sp) - return m_remote_platform_sp->GetSupportedArchitectureAtIndex(idx, arch); - - llvm::Triple triple; - // Set the OS to NetBSD - triple.setOS(llvm::Triple::NetBSD); - // Set the architecture - switch (idx) { - case 0: - triple.setArchName("x86_64"); - break; - case 1: - triple.setArchName("i386"); - break; - default: - return false; - } - // Leave the vendor as "llvm::Triple:UnknownVendor" and don't specify the - // vendor by calling triple.SetVendorName("unknown") so that it is a - // "unspecified unknown". This means when someone calls - // triple.GetVendorName() it will return an empty string which indicates - // that the vendor can be set when two architectures are merged - - // Now set the triple into "arch" and return true - arch.SetTriple(triple); - return true; + m_supported_architectures = CreateArchList( + {llvm::Triple::x86_64, llvm::Triple::x86}, llvm::Triple::NetBSD); } - return false; +} + +std::vector<ArchSpec> PlatformNetBSD::GetSupportedArchitectures() { + if (m_remote_platform_sp) + return m_remote_platform_sp->GetSupportedArchitectures(); + return m_supported_architectures; } void PlatformNetBSD::GetStatus(Stream &strm) { diff --git a/contrib/llvm-project/lldb/source/Plugins/Platform/NetBSD/PlatformNetBSD.h b/contrib/llvm-project/lldb/source/Plugins/Platform/NetBSD/PlatformNetBSD.h index e664f5181123..7158fbd26efb 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Platform/NetBSD/PlatformNetBSD.h +++ b/contrib/llvm-project/lldb/source/Plugins/Platform/NetBSD/PlatformNetBSD.h @@ -25,22 +25,24 @@ public: // lldb_private::PluginInterface functions static lldb::PlatformSP CreateInstance(bool force, const ArchSpec *arch); - static ConstString GetPluginNameStatic(bool is_host); - - static const char *GetPluginDescriptionStatic(bool is_host); + static llvm::StringRef GetPluginNameStatic(bool is_host) { + return is_host ? Platform::GetHostPlatformName() : "remote-netbsd"; + } - ConstString GetPluginName() override; + static llvm::StringRef GetPluginDescriptionStatic(bool is_host); - uint32_t GetPluginVersion() override { return 1; } + llvm::StringRef GetPluginName() override { + return GetPluginNameStatic(IsHost()); + } // lldb_private::Platform functions - const char *GetDescription() override { + llvm::StringRef GetDescription() override { return GetPluginDescriptionStatic(IsHost()); } void GetStatus(Stream &strm) override; - bool GetSupportedArchitectureAtIndex(uint32_t idx, ArchSpec &arch) override; + std::vector<ArchSpec> GetSupportedArchitectures() override; uint32_t GetResumeCountForLaunchInfo(ProcessLaunchInfo &launch_info) override; @@ -52,6 +54,8 @@ public: lldb::addr_t length, unsigned prot, unsigned flags, lldb::addr_t fd, lldb::addr_t offset) override; + + std::vector<ArchSpec> m_supported_architectures; }; } // namespace platform_netbsd diff --git a/contrib/llvm-project/lldb/source/Plugins/Platform/OpenBSD/PlatformOpenBSD.cpp b/contrib/llvm-project/lldb/source/Plugins/Platform/OpenBSD/PlatformOpenBSD.cpp index 012b688231a0..84d9ff799f47 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Platform/OpenBSD/PlatformOpenBSD.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Platform/OpenBSD/PlatformOpenBSD.cpp @@ -71,25 +71,10 @@ PlatformSP PlatformOpenBSD::CreateInstance(bool force, const ArchSpec *arch) { return PlatformSP(); } -ConstString PlatformOpenBSD::GetPluginNameStatic(bool is_host) { - if (is_host) { - static ConstString g_host_name(Platform::GetHostPlatformName()); - return g_host_name; - } else { - static ConstString g_remote_name("remote-openbsd"); - return g_remote_name; - } -} - -const char *PlatformOpenBSD::GetPluginDescriptionStatic(bool is_host) { +llvm::StringRef PlatformOpenBSD::GetPluginDescriptionStatic(bool is_host) { if (is_host) return "Local OpenBSD user platform plug-in."; - else - return "Remote OpenBSD user platform plug-in."; -} - -ConstString PlatformOpenBSD::GetPluginName() { - return GetPluginNameStatic(IsHost()); + return "Remote OpenBSD user platform plug-in."; } void PlatformOpenBSD::Initialize() { @@ -121,53 +106,21 @@ void PlatformOpenBSD::Terminate() { /// Default Constructor PlatformOpenBSD::PlatformOpenBSD(bool is_host) : PlatformPOSIX(is_host) // This is the local host platform -{} - -bool PlatformOpenBSD::GetSupportedArchitectureAtIndex(uint32_t idx, - ArchSpec &arch) { - if (IsHost()) { - ArchSpec hostArch = HostInfo::GetArchitecture(HostInfo::eArchKindDefault); - if (hostArch.GetTriple().isOSOpenBSD()) { - if (idx == 0) { - arch = hostArch; - return arch.IsValid(); - } - } +{ + if (is_host) { + m_supported_architectures.push_back(HostInfo::GetArchitecture()); } else { - if (m_remote_platform_sp) - return m_remote_platform_sp->GetSupportedArchitectureAtIndex(idx, arch); - - llvm::Triple triple; - // Set the OS to OpenBSD - triple.setOS(llvm::Triple::OpenBSD); - // Set the architecture - switch (idx) { - case 0: - triple.setArchName("x86_64"); - break; - case 1: - triple.setArchName("i386"); - break; - case 2: - triple.setArchName("aarch64"); - break; - case 3: - triple.setArchName("arm"); - break; - default: - return false; - } - // Leave the vendor as "llvm::Triple:UnknownVendor" and don't specify the - // vendor by calling triple.SetVendorName("unknown") so that it is a - // "unspecified unknown". This means when someone calls - // triple.GetVendorName() it will return an empty string which indicates - // that the vendor can be set when two architectures are merged - - // Now set the triple into "arch" and return true - arch.SetTriple(triple); - return true; + m_supported_architectures = + CreateArchList({llvm::Triple::x86_64, llvm::Triple::x86, + llvm::Triple::aarch64, llvm::Triple::arm}, + llvm::Triple::OpenBSD); } - return false; +} + +std::vector<ArchSpec> PlatformOpenBSD::GetSupportedArchitectures() { + if (m_remote_platform_sp) + return m_remote_platform_sp->GetSupportedArchitectures(); + return m_supported_architectures; } void PlatformOpenBSD::GetStatus(Stream &strm) { diff --git a/contrib/llvm-project/lldb/source/Plugins/Platform/OpenBSD/PlatformOpenBSD.h b/contrib/llvm-project/lldb/source/Plugins/Platform/OpenBSD/PlatformOpenBSD.h index e1402ae0ae9f..fd03988590ca 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Platform/OpenBSD/PlatformOpenBSD.h +++ b/contrib/llvm-project/lldb/source/Plugins/Platform/OpenBSD/PlatformOpenBSD.h @@ -25,22 +25,24 @@ public: // lldb_private::PluginInterface functions static lldb::PlatformSP CreateInstance(bool force, const ArchSpec *arch); - static ConstString GetPluginNameStatic(bool is_host); - - static const char *GetPluginDescriptionStatic(bool is_host); + static llvm::StringRef GetPluginNameStatic(bool is_host) { + return is_host ? Platform::GetHostPlatformName() : "remote-openbsd"; + } - ConstString GetPluginName() override; + static llvm::StringRef GetPluginDescriptionStatic(bool is_host); - uint32_t GetPluginVersion() override { return 1; } + llvm::StringRef GetPluginName() override { + return GetPluginNameStatic(IsHost()); + } // lldb_private::Platform functions - const char *GetDescription() override { + llvm::StringRef GetDescription() override { return GetPluginDescriptionStatic(IsHost()); } void GetStatus(Stream &strm) override; - bool GetSupportedArchitectureAtIndex(uint32_t idx, ArchSpec &arch) override; + std::vector<ArchSpec> GetSupportedArchitectures() override; bool CanDebugProcess() override; @@ -50,6 +52,8 @@ public: lldb::addr_t length, unsigned prot, unsigned flags, lldb::addr_t fd, lldb::addr_t offset) override; + + std::vector<ArchSpec> m_supported_architectures; }; } // namespace platform_openbsd diff --git a/contrib/llvm-project/lldb/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp b/contrib/llvm-project/lldb/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp index 7353132cd96f..719109c863e7 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp @@ -205,7 +205,7 @@ lldb_private::Status PlatformPOSIX::GetFile( // close dst LLDB_LOGF(log, "[GetFile] Using block by block transfer....\n"); Status error; - user_id_t fd_src = OpenFile(source, File::eOpenOptionRead, + user_id_t fd_src = OpenFile(source, File::eOpenOptionReadOnly, lldb::eFilePermissionsFileDefault, error); if (fd_src == UINT64_MAX) @@ -218,7 +218,7 @@ lldb_private::Status PlatformPOSIX::GetFile( permissions = lldb::eFilePermissionsFileDefault; user_id_t fd_dst = FileCache::GetInstance().OpenFile( - destination, File::eOpenOptionCanCreate | File::eOpenOptionWrite | + destination, File::eOpenOptionCanCreate | File::eOpenOptionWriteOnly | File::eOpenOptionTruncate, permissions, error); @@ -300,9 +300,9 @@ const lldb::UnixSignalsSP &PlatformPOSIX::GetRemoteUnixSignals() { Status PlatformPOSIX::ConnectRemote(Args &args) { Status error; if (IsHost()) { - error.SetErrorStringWithFormat( - "can't connect to the host platform '%s', always connected", - GetPluginName().GetCString()); + error.SetErrorStringWithFormatv( + "can't connect to the host platform '{0}', always connected", + GetPluginName()); } else { if (!m_remote_platform_sp) m_remote_platform_sp = @@ -344,9 +344,9 @@ Status PlatformPOSIX::DisconnectRemote() { Status error; if (IsHost()) { - error.SetErrorStringWithFormat( - "can't disconnect from the host platform '%s', always connected", - GetPluginName().GetCString()); + error.SetErrorStringWithFormatv( + "can't disconnect from the host platform '{0}', always connected", + GetPluginName()); } else { if (m_remote_platform_sp) error = m_remote_platform_sp->DisconnectRemote(); @@ -410,13 +410,11 @@ lldb::ProcessSP PlatformPOSIX::Attach(ProcessAttachInfo &attach_info, return process_sp; } -lldb::ProcessSP -PlatformPOSIX::DebugProcess(ProcessLaunchInfo &launch_info, Debugger &debugger, - Target *target, // Can be NULL, if NULL create a new - // target, else use existing one - Status &error) { +lldb::ProcessSP PlatformPOSIX::DebugProcess(ProcessLaunchInfo &launch_info, + Debugger &debugger, Target &target, + Status &error) { Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM)); - LLDB_LOG(log, "target {0}", target); + LLDB_LOG(log, "target {0}", &target); ProcessSP process_sp; @@ -442,29 +440,10 @@ PlatformPOSIX::DebugProcess(ProcessLaunchInfo &launch_info, Debugger &debugger, // worry about the target getting them as well. launch_info.SetLaunchInSeparateProcessGroup(true); - // Ensure we have a target. - if (target == nullptr) { - LLDB_LOG(log, "creating new target"); - TargetSP new_target_sp; - error = debugger.GetTargetList().CreateTarget( - debugger, "", "", eLoadDependentsNo, nullptr, new_target_sp); - if (error.Fail()) { - LLDB_LOG(log, "failed to create new target: {0}", error); - return process_sp; - } - - target = new_target_sp.get(); - if (!target) { - error.SetErrorString("CreateTarget() returned nullptr"); - LLDB_LOG(log, "error: {0}", error); - return process_sp; - } - } - // Now create the gdb-remote process. LLDB_LOG(log, "having target create process with gdb-remote plugin"); process_sp = - target->CreateProcess(launch_info.GetListener(), "gdb-remote", nullptr, + target.CreateProcess(launch_info.GetListener(), "gdb-remote", nullptr, true); if (!process_sp) { @@ -518,8 +497,8 @@ PlatformPOSIX::DebugProcess(ProcessLaunchInfo &launch_info, Debugger &debugger, LLDB_LOG(log, "not using process STDIO pty"); } else { LLDB_LOG(log, "{0}", error); - // FIXME figure out appropriate cleanup here. Do we delete the target? Do - // we delete the process? Does our caller do that? + // FIXME figure out appropriate cleanup here. Do we delete the process? + // Does our caller do that? } return process_sp; diff --git a/contrib/llvm-project/lldb/source/Plugins/Platform/POSIX/PlatformPOSIX.h b/contrib/llvm-project/lldb/source/Plugins/Platform/POSIX/PlatformPOSIX.h index 1cba4c5eb2e9..511797ce6bb7 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Platform/POSIX/PlatformPOSIX.h +++ b/contrib/llvm-project/lldb/source/Plugins/Platform/POSIX/PlatformPOSIX.h @@ -47,11 +47,7 @@ public: lldb::ProcessSP DebugProcess(lldb_private::ProcessLaunchInfo &launch_info, lldb_private::Debugger &debugger, - lldb_private::Target *target, // Can be nullptr, - // if nullptr - // create a new - // target, else use - // existing one + lldb_private::Target &target, lldb_private::Status &error) override; std::string GetPlatformSpecificConnectionInformation() override; diff --git a/contrib/llvm-project/lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp b/contrib/llvm-project/lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp index 528208665a4e..987f7c7f57e7 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp @@ -72,17 +72,12 @@ PlatformSP PlatformRemoteGDBServer::CreateInstance(bool force, return PlatformSP(); } -ConstString PlatformRemoteGDBServer::GetPluginNameStatic() { - static ConstString g_name("remote-gdb-server"); - return g_name; -} - -const char *PlatformRemoteGDBServer::GetDescriptionStatic() { +llvm::StringRef PlatformRemoteGDBServer::GetDescriptionStatic() { return "A platform that uses the GDB remote protocol as the communication " "transport."; } -const char *PlatformRemoteGDBServer::GetDescription() { +llvm::StringRef PlatformRemoteGDBServer::GetDescription() { if (m_platform_description.empty()) { if (IsConnected()) { // Send the get description packet @@ -94,76 +89,6 @@ const char *PlatformRemoteGDBServer::GetDescription() { return GetDescriptionStatic(); } -Status PlatformRemoteGDBServer::ResolveExecutable( - const ModuleSpec &module_spec, lldb::ModuleSP &exe_module_sp, - const FileSpecList *module_search_paths_ptr) { - // copied from PlatformRemoteiOS - - Status error; - // Nothing special to do here, just use the actual file and architecture - - ModuleSpec resolved_module_spec(module_spec); - - // Resolve any executable within an apk on Android? - // Host::ResolveExecutableInBundle (resolved_module_spec.GetFileSpec()); - - if (FileSystem::Instance().Exists(resolved_module_spec.GetFileSpec()) || - module_spec.GetUUID().IsValid()) { - if (resolved_module_spec.GetArchitecture().IsValid() || - resolved_module_spec.GetUUID().IsValid()) { - error = ModuleList::GetSharedModule(resolved_module_spec, exe_module_sp, - module_search_paths_ptr, nullptr, - nullptr); - - if (exe_module_sp && exe_module_sp->GetObjectFile()) - return error; - exe_module_sp.reset(); - } - // No valid architecture was specified or the exact arch wasn't found so - // ask the platform for the architectures that we should be using (in the - // correct order) and see if we can find a match that way - StreamString arch_names; - for (uint32_t idx = 0; GetSupportedArchitectureAtIndex( - idx, resolved_module_spec.GetArchitecture()); - ++idx) { - error = ModuleList::GetSharedModule(resolved_module_spec, exe_module_sp, - module_search_paths_ptr, nullptr, - nullptr); - // Did we find an executable using one of the - if (error.Success()) { - if (exe_module_sp && exe_module_sp->GetObjectFile()) - break; - else - error.SetErrorToGenericError(); - } - - if (idx > 0) - arch_names.PutCString(", "); - arch_names.PutCString( - resolved_module_spec.GetArchitecture().GetArchitectureName()); - } - - if (error.Fail() || !exe_module_sp) { - if (FileSystem::Instance().Readable(resolved_module_spec.GetFileSpec())) { - error.SetErrorStringWithFormat( - "'%s' doesn't contain any '%s' platform architectures: %s", - resolved_module_spec.GetFileSpec().GetPath().c_str(), - GetPluginName().GetCString(), arch_names.GetData()); - } else { - error.SetErrorStringWithFormat( - "'%s' is not readable", - resolved_module_spec.GetFileSpec().GetPath().c_str()); - } - } - } else { - error.SetErrorStringWithFormat( - "'%s' does not exist", - resolved_module_spec.GetFileSpec().GetPath().c_str()); - } - - return error; -} - bool PlatformRemoteGDBServer::GetModuleSpec(const FileSpec &module_file_spec, const ArchSpec &arch, ModuleSpec &module_spec) { @@ -214,21 +139,6 @@ PlatformRemoteGDBServer::PlatformRemoteGDBServer() /// inherited from by the plug-in instance. PlatformRemoteGDBServer::~PlatformRemoteGDBServer() = default; -bool PlatformRemoteGDBServer::GetSupportedArchitectureAtIndex(uint32_t idx, - ArchSpec &arch) { - ArchSpec remote_arch = m_gdb_client.GetSystemArchitecture(); - - if (idx == 0) { - arch = remote_arch; - return arch.IsValid(); - } else if (idx == 1 && remote_arch.IsValid() && - remote_arch.GetTriple().isArch64Bit()) { - arch.SetTriple(remote_arch.GetTriple().get32BitArchVariant()); - return arch.IsValid(); - } - return false; -} - size_t PlatformRemoteGDBServer::GetSoftwareBreakpointTrapOpcode( Target &target, BreakpointSite *bp_site) { // This isn't needed if the z/Z packets are supported in the GDB remote @@ -241,12 +151,13 @@ bool PlatformRemoteGDBServer::GetRemoteOSVersion() { return !m_os_version.empty(); } -bool PlatformRemoteGDBServer::GetRemoteOSBuildString(std::string &s) { - return m_gdb_client.GetOSBuildString(s); +llvm::Optional<std::string> PlatformRemoteGDBServer::GetRemoteOSBuildString() { + return m_gdb_client.GetOSBuildString(); } -bool PlatformRemoteGDBServer::GetRemoteOSKernelDescription(std::string &s) { - return m_gdb_client.GetOSKernelDescription(s); +llvm::Optional<std::string> +PlatformRemoteGDBServer::GetRemoteOSKernelDescription() { + return m_gdb_client.GetOSKernelDescription(); } // Remote Platform subclasses need to override this function @@ -305,14 +216,13 @@ Status PlatformRemoteGDBServer::ConnectRemote(Args &args) { if (!url) return Status("URL is null."); - int port; - llvm::StringRef scheme, hostname, pathname; - if (!UriParser::Parse(url, scheme, hostname, port, pathname)) + llvm::Optional<URI> parsed_url = URI::Parse(url); + if (!parsed_url) return Status("Invalid URL: %s", url); // We're going to reuse the hostname when we connect to the debugserver. - m_platform_scheme = std::string(scheme); - m_platform_hostname = std::string(hostname); + m_platform_scheme = parsed_url->scheme.str(); + m_platform_hostname = parsed_url->hostname.str(); m_gdb_client.SetConnection(std::make_unique<ConnectionFileDescriptor>()); if (repro::Reproducer::Instance().IsReplaying()) { @@ -337,6 +247,15 @@ Status PlatformRemoteGDBServer::ConnectRemote(Args &args) { // now. if (m_working_dir) m_gdb_client.SetWorkingDir(m_working_dir); + + m_supported_architectures.clear(); + ArchSpec remote_arch = m_gdb_client.GetSystemArchitecture(); + if (remote_arch) { + m_supported_architectures.push_back(remote_arch); + if (remote_arch.GetTriple().isArch64Bit()) + m_supported_architectures.push_back( + ArchSpec(remote_arch.GetTriple().get32BitArchVariant())); + } } else { m_gdb_client.Disconnect(); if (error.Success()) @@ -475,11 +394,10 @@ Status PlatformRemoteGDBServer::KillProcess(const lldb::pid_t pid) { return Status(); } -lldb::ProcessSP PlatformRemoteGDBServer::DebugProcess( - ProcessLaunchInfo &launch_info, Debugger &debugger, - Target *target, // Can be NULL, if NULL create a new target, else use - // existing one - Status &error) { +lldb::ProcessSP +PlatformRemoteGDBServer::DebugProcess(ProcessLaunchInfo &launch_info, + Debugger &debugger, Target &target, + Status &error) { lldb::ProcessSP process_sp; if (IsRemote()) { if (IsConnected()) { @@ -489,32 +407,21 @@ lldb::ProcessSP PlatformRemoteGDBServer::DebugProcess( error.SetErrorStringWithFormat("unable to launch a GDB server on '%s'", GetHostname()); } else { - if (target == nullptr) { - TargetSP new_target_sp; - - error = debugger.GetTargetList().CreateTarget( - debugger, "", "", eLoadDependentsNo, nullptr, new_target_sp); - target = new_target_sp.get(); - } else - error.Clear(); - - if (target && error.Success()) { - // The darwin always currently uses the GDB remote debugger plug-in - // so even when debugging locally we are debugging remotely! - process_sp = target->CreateProcess(launch_info.GetListener(), - "gdb-remote", nullptr, true); - - if (process_sp) { + // The darwin always currently uses the GDB remote debugger plug-in + // so even when debugging locally we are debugging remotely! + process_sp = target.CreateProcess(launch_info.GetListener(), + "gdb-remote", nullptr, true); + + if (process_sp) { + error = process_sp->ConnectRemote(connect_url.c_str()); + // Retry the connect remote one time... + if (error.Fail()) error = process_sp->ConnectRemote(connect_url.c_str()); - // Retry the connect remote one time... - if (error.Fail()) - error = process_sp->ConnectRemote(connect_url.c_str()); - if (error.Success()) - error = process_sp->Launch(launch_info); - else if (debugserver_pid != LLDB_INVALID_PROCESS_ID) { - printf("error: connect remote failed (%s)\n", error.AsCString()); - KillSpawnedProcess(debugserver_pid); - } + if (error.Success()) + error = process_sp->Launch(launch_info); + else if (debugserver_pid != LLDB_INVALID_PROCESS_ID) { + printf("error: connect remote failed (%s)\n", error.AsCString()); + KillSpawnedProcess(debugserver_pid); } } } diff --git a/contrib/llvm-project/lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h b/contrib/llvm-project/lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h index e43cd0e55c6d..f594f43b3f13 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h +++ b/contrib/llvm-project/lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h @@ -28,28 +28,22 @@ public: static lldb::PlatformSP CreateInstance(bool force, const ArchSpec *arch); - static ConstString GetPluginNameStatic(); + static llvm::StringRef GetPluginNameStatic() { return "remote-gdb-server"; } - static const char *GetDescriptionStatic(); + static llvm::StringRef GetDescriptionStatic(); PlatformRemoteGDBServer(); ~PlatformRemoteGDBServer() override; // lldb_private::PluginInterface functions - ConstString GetPluginName() override { return GetPluginNameStatic(); } - - uint32_t GetPluginVersion() override { return 1; } + llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); } // lldb_private::Platform functions - Status - ResolveExecutable(const ModuleSpec &module_spec, lldb::ModuleSP &module_sp, - const FileSpecList *module_search_paths_ptr) override; - bool GetModuleSpec(const FileSpec &module_file_spec, const ArchSpec &arch, ModuleSpec &module_spec) override; - const char *GetDescription() override; + llvm::StringRef GetDescription() override; Status GetFileWithUUID(const FileSpec &platform_file, const UUID *uuid_ptr, FileSpec &local_file) override; @@ -64,10 +58,7 @@ public: Status KillProcess(const lldb::pid_t pid) override; lldb::ProcessSP DebugProcess(ProcessLaunchInfo &launch_info, - Debugger &debugger, - Target *target, // Can be NULL, if NULL create a - // new target, else use existing - // one + Debugger &debugger, Target &target, Status &error) override; lldb::ProcessSP Attach(ProcessAttachInfo &attach_info, Debugger &debugger, @@ -75,16 +66,18 @@ public: // target, else use existing one Status &error) override; - bool GetSupportedArchitectureAtIndex(uint32_t idx, ArchSpec &arch) override; + std::vector<ArchSpec> GetSupportedArchitectures() override { + return m_supported_architectures; + } size_t GetSoftwareBreakpointTrapOpcode(Target &target, BreakpointSite *bp_site) override; bool GetRemoteOSVersion() override; - bool GetRemoteOSBuildString(std::string &s) override; + llvm::Optional<std::string> GetRemoteOSBuildString() override; - bool GetRemoteOSKernelDescription(std::string &s) override; + llvm::Optional<std::string> GetRemoteOSKernelDescription() override; // Remote Platform subclasses need to override this function ArchSpec GetRemoteSystemArchitecture() override; @@ -191,6 +184,8 @@ private: llvm::Optional<std::string> DoGetUserName(UserIDResolver::id_t uid) override; llvm::Optional<std::string> DoGetGroupName(UserIDResolver::id_t uid) override; + std::vector<ArchSpec> m_supported_architectures; + PlatformRemoteGDBServer(const PlatformRemoteGDBServer &) = delete; const PlatformRemoteGDBServer & operator=(const PlatformRemoteGDBServer &) = delete; diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeProcessFreeBSD.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeProcessFreeBSD.cpp index d6426b3d2367..a62d3c1ba052 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeProcessFreeBSD.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeProcessFreeBSD.cpp @@ -130,8 +130,12 @@ NativeProcessFreeBSD::Factory::Attach( NativeProcessFreeBSD::Extension NativeProcessFreeBSD::Factory::GetSupportedExtensions() const { - return Extension::multiprocess | Extension::fork | Extension::vfork | - Extension::pass_signals | Extension::auxv | Extension::libraries_svr4; + return +#if defined(PT_COREDUMP) + Extension::savecore | +#endif + Extension::multiprocess | Extension::fork | Extension::vfork | + Extension::pass_signals | Extension::auxv | Extension::libraries_svr4; } // Public Instance Methods @@ -1009,3 +1013,36 @@ void NativeProcessFreeBSD::MonitorClone(::pid_t child_pid, bool is_vfork, } } } + +llvm::Expected<std::string> +NativeProcessFreeBSD::SaveCore(llvm::StringRef path_hint) { +#if defined(PT_COREDUMP) + using namespace llvm::sys::fs; + + llvm::SmallString<128> path{path_hint}; + Status error; + struct ptrace_coredump pc = {}; + + // Try with the suggested path first. If there is no suggested path or it + // failed to open, use a temporary file. + if (path.empty() || + openFile(path, pc.pc_fd, CD_CreateNew, FA_Write, OF_None)) { + if (std::error_code errc = + createTemporaryFile("lldb", "core", pc.pc_fd, path)) + return llvm::createStringError(errc, "Unable to create a temporary file"); + } + error = PtraceWrapper(PT_COREDUMP, GetID(), &pc, sizeof(pc)); + + std::error_code close_err = closeFile(pc.pc_fd); + if (error.Fail()) + return error.ToError(); + if (close_err) + return llvm::createStringError( + close_err, "Unable to close the core dump after writing"); + return path.str().str(); +#else // !defined(PT_COREDUMP) + return llvm::createStringError( + llvm::inconvertibleErrorCode(), + "PT_COREDUMP not supported in the FreeBSD version used to build LLDB"); +#endif +} diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeProcessFreeBSD.h b/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeProcessFreeBSD.h index 7ec9d17d4cf4..44b8a53699bb 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeProcessFreeBSD.h +++ b/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeProcessFreeBSD.h @@ -91,6 +91,8 @@ public: bool SupportHardwareSingleStepping() const; + llvm::Expected<std::string> SaveCore(llvm::StringRef path_hint) override; + protected: llvm::Expected<llvm::ArrayRef<uint8_t>> GetSoftwareBreakpointTrapOpcode(size_t size_hint) override; diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_mips64.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_mips64.cpp index 8e722c09314c..d93b7fd33815 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_mips64.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_mips64.cpp @@ -15,6 +15,7 @@ #include "lldb/Utility/Status.h" #include "Plugins/Process/FreeBSD/NativeProcessFreeBSD.h" +#include "Plugins/Process/Utility/lldb-mips-freebsd-register-enums.h" // clang-format off #include <sys/param.h> @@ -59,11 +60,32 @@ uint32_t NativeRegisterContextFreeBSD_mips64::GetUserRegisterCount() const { return count; } +llvm::Optional<NativeRegisterContextFreeBSD_mips64::RegSetKind> +NativeRegisterContextFreeBSD_mips64::GetSetForNativeRegNum( + uint32_t reg_num) const { + switch (GetRegisterInfoInterface().GetTargetArchitecture().GetMachine()) { + case llvm::Triple::mips64: + if (reg_num >= k_first_gpr_mips64 && reg_num <= k_last_gpr_mips64) + return GPRegSet; + if (reg_num >= k_first_fpr_mips64 && reg_num <= k_last_fpr_mips64) + return FPRegSet; + break; + default: + llvm_unreachable("Unhandled target architecture."); + } + + llvm_unreachable("Register does not belong to any register set"); +} + Status NativeRegisterContextFreeBSD_mips64::ReadRegisterSet(RegSetKind set) { switch (set) { case GPRegSet: return NativeProcessFreeBSD::PtraceWrapper(PT_GETREGS, m_thread.GetID(), m_reg_data.data()); + case FPRegSet: + return NativeProcessFreeBSD::PtraceWrapper( + PT_GETFPREGS, m_thread.GetID(), + m_reg_data.data() + GetRegisterInfo().GetGPRSize()); } llvm_unreachable("NativeRegisterContextFreeBSD_mips64::ReadRegisterSet"); } @@ -73,6 +95,10 @@ Status NativeRegisterContextFreeBSD_mips64::WriteRegisterSet(RegSetKind set) { case GPRegSet: return NativeProcessFreeBSD::PtraceWrapper(PT_SETREGS, m_thread.GetID(), m_reg_data.data()); + case FPRegSet: + return NativeProcessFreeBSD::PtraceWrapper( + PT_SETFPREGS, m_thread.GetID(), + m_reg_data.data() + GetRegisterInfo().GetGPRSize()); } llvm_unreachable("NativeRegisterContextFreeBSD_mips64::WriteRegisterSet"); } @@ -94,7 +120,16 @@ NativeRegisterContextFreeBSD_mips64::ReadRegister(const RegisterInfo *reg_info, ? reg_info->name : "<unknown register>"); - RegSetKind set = GPRegSet; + llvm::Optional<RegSetKind> opt_set = GetSetForNativeRegNum(reg); + if (!opt_set) { + // This is likely an internal register for lldb use only and should not be + // directly queried. + error.SetErrorStringWithFormat("register \"%s\" is in unrecognized set", + reg_info->name); + return error; + } + + RegSetKind set = opt_set.getValue(); error = ReadRegisterSet(set); if (error.Fail()) return error; @@ -119,7 +154,16 @@ Status NativeRegisterContextFreeBSD_mips64::WriteRegister( ? reg_info->name : "<unknown register>"); - RegSetKind set = GPRegSet; + llvm::Optional<RegSetKind> opt_set = GetSetForNativeRegNum(reg); + if (!opt_set) { + // This is likely an internal register for lldb use only and should not be + // directly queried. + error.SetErrorStringWithFormat("register \"%s\" is in unrecognized set", + reg_info->name); + return error; + } + + RegSetKind set = opt_set.getValue(); error = ReadRegisterSet(set); if (error.Fail()) return error; @@ -139,6 +183,10 @@ Status NativeRegisterContextFreeBSD_mips64::ReadAllRegisterValues( if (error.Fail()) return error; + error = ReadRegisterSet(FPRegSet); + if (error.Fail()) + return error; + data_sp.reset(new DataBufferHeap(m_reg_data.size(), 0)); uint8_t *dst = data_sp->GetBytes(); ::memcpy(dst, m_reg_data.data(), m_reg_data.size()); @@ -175,7 +223,11 @@ Status NativeRegisterContextFreeBSD_mips64::WriteAllRegisterValues( } ::memcpy(m_reg_data.data(), src, m_reg_data.size()); - return WriteRegisterSet(GPRegSet); + error = WriteRegisterSet(GPRegSet); + if (error.Fail()) + return error; + + return WriteRegisterSet(FPRegSet); } llvm::Error NativeRegisterContextFreeBSD_mips64::CopyHardwareWatchpointsFrom( diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_mips64.h b/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_mips64.h index 6a3eb86a9231..8e300ed829c9 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_mips64.h +++ b/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_mips64.h @@ -54,8 +54,11 @@ public: private: enum RegSetKind { GPRegSet, + FPRegSet, }; - std::array<uint8_t, sizeof(reg)> m_reg_data; + std::array<uint8_t, sizeof(reg) + sizeof(fpreg)> m_reg_data; + + llvm::Optional<RegSetKind> GetSetForNativeRegNum(uint32_t reg_num) const; Status ReadRegisterSet(RegSetKind set); Status WriteRegisterSet(RegSetKind set); diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/NetBSD/NativeProcessNetBSD.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/NetBSD/NativeProcessNetBSD.cpp index 9ea1a16b8785..0420d00e39d6 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/NetBSD/NativeProcessNetBSD.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Process/NetBSD/NativeProcessNetBSD.cpp @@ -136,7 +136,8 @@ NativeProcessNetBSD::Factory::Attach( NativeProcessNetBSD::Extension NativeProcessNetBSD::Factory::GetSupportedExtensions() const { return Extension::multiprocess | Extension::fork | Extension::vfork | - Extension::pass_signals | Extension::auxv | Extension::libraries_svr4; + Extension::pass_signals | Extension::auxv | Extension::libraries_svr4 | + Extension::savecore; } // Public Instance Methods @@ -1073,3 +1074,27 @@ void NativeProcessNetBSD::MonitorClone(::pid_t child_pid, bool is_vfork, } } } + +llvm::Expected<std::string> +NativeProcessNetBSD::SaveCore(llvm::StringRef path_hint) { + llvm::SmallString<128> path{path_hint}; + Status error; + + // Try with the suggested path first. + if (!path.empty()) { + error = PtraceWrapper(PT_DUMPCORE, GetID(), path.data(), path.size()); + if (!error.Fail()) + return path.str().str(); + + // If the request errored, fall back to a generic temporary file. + } + + if (std::error_code errc = + llvm::sys::fs::createTemporaryFile("lldb", "core", path)) + return llvm::createStringError(errc, "Unable to create a temporary file"); + + error = PtraceWrapper(PT_DUMPCORE, GetID(), path.data(), path.size()); + if (error.Fail()) + return error.ToError(); + return path.str().str(); +} diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/NetBSD/NativeProcessNetBSD.h b/contrib/llvm-project/lldb/source/Plugins/Process/NetBSD/NativeProcessNetBSD.h index 90d32aa6069d..3f54d02a9075 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/NetBSD/NativeProcessNetBSD.h +++ b/contrib/llvm-project/lldb/source/Plugins/Process/NetBSD/NativeProcessNetBSD.h @@ -88,6 +88,8 @@ public: static Status PtraceWrapper(int req, lldb::pid_t pid, void *addr = nullptr, int data = 0, int *result = nullptr); + llvm::Expected<std::string> SaveCore(llvm::StringRef path_hint) override; + private: MainLoop::SignalHandleUP m_sigchld_handle; ArchSpec m_arch; diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/GDBRemoteSignals.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/GDBRemoteSignals.cpp index 427225c14d3b..15981a2c1cb8 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/GDBRemoteSignals.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/GDBRemoteSignals.cpp @@ -15,4 +15,167 @@ GDBRemoteSignals::GDBRemoteSignals() : UnixSignals() { Reset(); } GDBRemoteSignals::GDBRemoteSignals(const lldb::UnixSignalsSP &rhs) : UnixSignals(*rhs) {} -void GDBRemoteSignals::Reset() { m_signals.clear(); } +void GDBRemoteSignals::Reset() { + m_signals.clear(); + // clang-format off + // SIGNO NAME SUPPRESS STOP NOTIFY DESCRIPTION + // ====== ============== ======== ====== ====== =================================================== + AddSignal(1, "SIGHUP", false, true, true, "hangup"); + AddSignal(2, "SIGINT", true, true, true, "interrupt"); + AddSignal(3, "SIGQUIT", false, true, true, "quit"); + AddSignal(4, "SIGILL", false, true, true, "illegal instruction"); + AddSignal(5, "SIGTRAP", true, true, true, "trace trap (not reset when caught)"); + AddSignal(6, "SIGABRT", false, true, true, "abort()/IOT trap", "SIGIOT"); + AddSignal(7, "SIGEMT", false, true, true, "emulation trap"); + AddSignal(8, "SIGFPE", false, true, true, "floating point exception"); + AddSignal(9, "SIGKILL", false, true, true, "kill"); + AddSignal(10, "SIGBUS", false, true, true, "bus error"); + AddSignal(11, "SIGSEGV", false, true, true, "segmentation violation"); + AddSignal(12, "SIGSYS", false, true, true, "invalid system call"); + AddSignal(13, "SIGPIPE", false, true, true, "write to pipe with reading end closed"); + AddSignal(14, "SIGALRM", false, false, false, "alarm"); + AddSignal(15, "SIGTERM", false, true, true, "termination requested"); + AddSignal(16, "SIGURG", false, true, true, "urgent data on socket"); + AddSignal(17, "SIGSTOP", true, true, true, "process stop"); + AddSignal(18, "SIGTSTP", false, true, true, "tty stop"); + AddSignal(19, "SIGCONT", false, false, true, "process continue"); + AddSignal(20, "SIGCHLD", false, false, true, "child status has changed", "SIGCLD"); + AddSignal(21, "SIGTTIN", false, true, true, "background tty read"); + AddSignal(22, "SIGTTOU", false, true, true, "background tty write"); + AddSignal(23, "SIGIO", false, true, true, "input/output ready/Pollable event"); + AddSignal(24, "SIGXCPU", false, true, true, "CPU resource exceeded"); + AddSignal(25, "SIGXFSZ", false, true, true, "file size limit exceeded"); + AddSignal(26, "SIGVTALRM", false, true, true, "virtual time alarm"); + AddSignal(27, "SIGPROF", false, false, false, "profiling time alarm"); + AddSignal(28, "SIGWINCH", false, true, true, "window size changes"); + AddSignal(29, "SIGLOST", false, true, true, "resource lost"); + AddSignal(30, "SIGUSR1", false, true, true, "user defined signal 1"); + AddSignal(31, "SIGUSR2", false, true, true, "user defined signal 2"); + AddSignal(32, "SIGPWR", false, true, true, "power failure"); + AddSignal(33, "SIGPOLL", false, true, true, "pollable event"); + AddSignal(34, "SIGWIND", false, true, true, "SIGWIND"); + AddSignal(35, "SIGPHONE", false, true, true, "SIGPHONE"); + AddSignal(36, "SIGWAITING", false, true, true, "process's LWPs are blocked"); + AddSignal(37, "SIGLWP", false, true, true, "signal LWP"); + AddSignal(38, "SIGDANGER", false, true, true, "swap space dangerously low"); + AddSignal(39, "SIGGRANT", false, true, true, "monitor mode granted"); + AddSignal(40, "SIGRETRACT", false, true, true, "need to relinquish monitor mode"); + AddSignal(41, "SIGMSG", false, true, true, "monitor mode data available"); + AddSignal(42, "SIGSOUND", false, true, true, "sound completed"); + AddSignal(43, "SIGSAK", false, true, true, "secure attention"); + AddSignal(44, "SIGPRIO", false, true, true, "SIGPRIO"); + + AddSignal(45, "SIG33", false, false, false, "real-time event 33"); + AddSignal(46, "SIG34", false, false, false, "real-time event 34"); + AddSignal(47, "SIG35", false, false, false, "real-time event 35"); + AddSignal(48, "SIG36", false, false, false, "real-time event 36"); + AddSignal(49, "SIG37", false, false, false, "real-time event 37"); + AddSignal(50, "SIG38", false, false, false, "real-time event 38"); + AddSignal(51, "SIG39", false, false, false, "real-time event 39"); + AddSignal(52, "SIG40", false, false, false, "real-time event 40"); + AddSignal(53, "SIG41", false, false, false, "real-time event 41"); + AddSignal(54, "SIG42", false, false, false, "real-time event 42"); + AddSignal(55, "SIG43", false, false, false, "real-time event 43"); + AddSignal(56, "SIG44", false, false, false, "real-time event 44"); + AddSignal(57, "SIG45", false, false, false, "real-time event 45"); + AddSignal(58, "SIG46", false, false, false, "real-time event 46"); + AddSignal(59, "SIG47", false, false, false, "real-time event 47"); + AddSignal(60, "SIG48", false, false, false, "real-time event 48"); + AddSignal(61, "SIG49", false, false, false, "real-time event 49"); + AddSignal(62, "SIG50", false, false, false, "real-time event 50"); + AddSignal(63, "SIG51", false, false, false, "real-time event 51"); + AddSignal(64, "SIG52", false, false, false, "real-time event 52"); + AddSignal(65, "SIG53", false, false, false, "real-time event 53"); + AddSignal(66, "SIG54", false, false, false, "real-time event 54"); + AddSignal(67, "SIG55", false, false, false, "real-time event 55"); + AddSignal(68, "SIG56", false, false, false, "real-time event 56"); + AddSignal(69, "SIG57", false, false, false, "real-time event 57"); + AddSignal(70, "SIG58", false, false, false, "real-time event 58"); + AddSignal(71, "SIG59", false, false, false, "real-time event 59"); + AddSignal(72, "SIG60", false, false, false, "real-time event 60"); + AddSignal(73, "SIG61", false, false, false, "real-time event 61"); + AddSignal(74, "SIG62", false, false, false, "real-time event 62"); + AddSignal(75, "SIG63", false, false, false, "real-time event 63"); + + AddSignal(76, "SIGCANCEL", false, true, true, "LWP internal signal"); + + AddSignal(77, "SIG32", false, false, false, "real-time event 32"); + AddSignal(78, "SIG64", false, false, false, "real-time event 64"); + AddSignal(79, "SIG65", false, false, false, "real-time event 65"); + AddSignal(80, "SIG66", false, false, false, "real-time event 66"); + AddSignal(81, "SIG67", false, false, false, "real-time event 67"); + AddSignal(82, "SIG68", false, false, false, "real-time event 68"); + AddSignal(83, "SIG69", false, false, false, "real-time event 69"); + AddSignal(84, "SIG70", false, false, false, "real-time event 70"); + AddSignal(85, "SIG71", false, false, false, "real-time event 71"); + AddSignal(86, "SIG72", false, false, false, "real-time event 72"); + AddSignal(87, "SIG73", false, false, false, "real-time event 73"); + AddSignal(88, "SIG74", false, false, false, "real-time event 74"); + AddSignal(89, "SIG75", false, false, false, "real-time event 75"); + AddSignal(90, "SIG76", false, false, false, "real-time event 76"); + AddSignal(91, "SIG77", false, false, false, "real-time event 77"); + AddSignal(92, "SIG78", false, false, false, "real-time event 78"); + AddSignal(93, "SIG79", false, false, false, "real-time event 79"); + AddSignal(94, "SIG80", false, false, false, "real-time event 80"); + AddSignal(95, "SIG81", false, false, false, "real-time event 81"); + AddSignal(96, "SIG82", false, false, false, "real-time event 82"); + AddSignal(97, "SIG83", false, false, false, "real-time event 83"); + AddSignal(98, "SIG84", false, false, false, "real-time event 84"); + AddSignal(99, "SIG85", false, false, false, "real-time event 85"); + AddSignal(100, "SIG86", false, false, false, "real-time event 86"); + AddSignal(101, "SIG87", false, false, false, "real-time event 87"); + AddSignal(102, "SIG88", false, false, false, "real-time event 88"); + AddSignal(103, "SIG89", false, false, false, "real-time event 89"); + AddSignal(104, "SIG90", false, false, false, "real-time event 90"); + AddSignal(105, "SIG91", false, false, false, "real-time event 91"); + AddSignal(106, "SIG92", false, false, false, "real-time event 92"); + AddSignal(107, "SIG93", false, false, false, "real-time event 93"); + AddSignal(108, "SIG94", false, false, false, "real-time event 94"); + AddSignal(109, "SIG95", false, false, false, "real-time event 95"); + AddSignal(110, "SIG96", false, false, false, "real-time event 96"); + AddSignal(111, "SIG97", false, false, false, "real-time event 97"); + AddSignal(112, "SIG98", false, false, false, "real-time event 98"); + AddSignal(113, "SIG99", false, false, false, "real-time event 99"); + AddSignal(114, "SIG100", false, false, false, "real-time event 100"); + AddSignal(115, "SIG101", false, false, false, "real-time event 101"); + AddSignal(116, "SIG102", false, false, false, "real-time event 102"); + AddSignal(117, "SIG103", false, false, false, "real-time event 103"); + AddSignal(118, "SIG104", false, false, false, "real-time event 104"); + AddSignal(119, "SIG105", false, false, false, "real-time event 105"); + AddSignal(120, "SIG106", false, false, false, "real-time event 106"); + AddSignal(121, "SIG107", false, false, false, "real-time event 107"); + AddSignal(122, "SIG108", false, false, false, "real-time event 108"); + AddSignal(123, "SIG109", false, false, false, "real-time event 109"); + AddSignal(124, "SIG110", false, false, false, "real-time event 110"); + AddSignal(125, "SIG111", false, false, false, "real-time event 111"); + AddSignal(126, "SIG112", false, false, false, "real-time event 112"); + AddSignal(127, "SIG113", false, false, false, "real-time event 113"); + AddSignal(128, "SIG114", false, false, false, "real-time event 114"); + AddSignal(129, "SIG115", false, false, false, "real-time event 115"); + AddSignal(130, "SIG116", false, false, false, "real-time event 116"); + AddSignal(131, "SIG117", false, false, false, "real-time event 117"); + AddSignal(132, "SIG118", false, false, false, "real-time event 118"); + AddSignal(133, "SIG119", false, false, false, "real-time event 119"); + AddSignal(134, "SIG120", false, false, false, "real-time event 120"); + AddSignal(135, "SIG121", false, false, false, "real-time event 121"); + AddSignal(136, "SIG122", false, false, false, "real-time event 122"); + AddSignal(137, "SIG123", false, false, false, "real-time event 123"); + AddSignal(138, "SIG124", false, false, false, "real-time event 124"); + AddSignal(139, "SIG125", false, false, false, "real-time event 125"); + AddSignal(140, "SIG126", false, false, false, "real-time event 126"); + AddSignal(141, "SIG127", false, false, false, "real-time event 127"); + + AddSignal(142, "SIGINFO", false, true, true, "information request"); + AddSignal(143, "unknown", false, true, true, "unknown signal"); + + AddSignal(145, "EXC_BAD_ACCESS", false, true, true, "could not access memory"); + AddSignal(146, "EXC_BAD_INSTRUCTION", false, true, true, "illegal instruction/operand"); + AddSignal(147, "EXC_ARITHMETIC", false, true, true, "arithmetic exception"); + AddSignal(148, "EXC_EMULATION", false, true, true, "emulation instruction"); + AddSignal(149, "EXC_SOFTWARE", false, true, true, "software generated exception"); + AddSignal(150, "EXC_BREAKPOINT", false, true, true, "breakpoint"); + + AddSignal(151, "SIGLIBRT", false, true, true, "librt internal signal"); + + // clang-format on +} diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/GDBRemoteSignals.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/GDBRemoteSignals.h index d37757ab60a5..4c260b94eba8 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/GDBRemoteSignals.h +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/GDBRemoteSignals.h @@ -13,7 +13,8 @@ namespace lldb_private { -/// Empty set of Unix signals to be filled by PlatformRemoteGDBServer +/// Initially carries signals defined by the GDB Remote Serial Protocol. +/// Can be filled with platform's signals through PlatformRemoteGDBServer. class GDBRemoteSignals : public UnixSignals { public: GDBRemoteSignals(); diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/InferiorCallPOSIX.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/InferiorCallPOSIX.cpp index 0f331933f2ea..5091f68a9acf 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/InferiorCallPOSIX.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/InferiorCallPOSIX.cpp @@ -8,12 +8,13 @@ #include "InferiorCallPOSIX.h" #include "lldb/Core/Address.h" +#include "lldb/Core/Module.h" #include "lldb/Core/StreamFile.h" #include "lldb/Core/ValueObject.h" #include "lldb/Expression/DiagnosticManager.h" #include "lldb/Host/Config.h" -#include "lldb/Symbol/TypeSystem.h" #include "lldb/Symbol/SymbolContext.h" +#include "lldb/Symbol/TypeSystem.h" #include "lldb/Target/ExecutionContext.h" #include "lldb/Target/Platform.h" #include "lldb/Target/Process.h" @@ -41,12 +42,13 @@ bool lldb_private::InferiorCallMmap(Process *process, addr_t &allocated_addr, if (thread == nullptr) return false; - const bool include_symbols = true; - const bool include_inlines = false; + ModuleFunctionSearchOptions function_options; + function_options.include_symbols = true; + function_options.include_inlines = false; + SymbolContextList sc_list; process->GetTarget().GetImages().FindFunctions( - ConstString("mmap"), eFunctionNameTypeFull, include_symbols, - include_inlines, sc_list); + ConstString("mmap"), eFunctionNameTypeFull, function_options, sc_list); const uint32_t count = sc_list.GetSize(); if (count > 0) { SymbolContext sc; @@ -135,12 +137,13 @@ bool lldb_private::InferiorCallMunmap(Process *process, addr_t addr, if (thread == nullptr) return false; - const bool include_symbols = true; - const bool include_inlines = false; + ModuleFunctionSearchOptions function_options; + function_options.include_symbols = true; + function_options.include_inlines = false; + SymbolContextList sc_list; process->GetTarget().GetImages().FindFunctions( - ConstString("munmap"), eFunctionNameTypeFull, include_symbols, - include_inlines, sc_list); + ConstString("munmap"), eFunctionNameTypeFull, function_options, sc_list); const uint32_t count = sc_list.GetSize(); if (count > 0) { SymbolContext sc; diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_arm.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_arm.cpp index 7e38091738e3..e1d3b6ecd7d0 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_arm.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_arm.cpp @@ -177,7 +177,7 @@ enum { {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \ LLDB_INVALID_REGNUM }, \ - nullptr, nullptr, nullptr, 0 + nullptr, nullptr, #define REG_CONTEXT_SIZE \ (sizeof(RegisterContextDarwin_arm::GPR) + \ sizeof(RegisterContextDarwin_arm::FPU) + \ @@ -200,8 +200,7 @@ static RegisterInfo g_register_infos[] = { {ehframe_r0, dwarf_r0, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_r0}, nullptr, nullptr, - nullptr, - 0}, + }, {"r1", nullptr, 4, @@ -211,8 +210,7 @@ static RegisterInfo g_register_infos[] = { {ehframe_r1, dwarf_r1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_r1}, nullptr, nullptr, - nullptr, - 0}, + }, {"r2", nullptr, 4, @@ -222,8 +220,7 @@ static RegisterInfo g_register_infos[] = { {ehframe_r2, dwarf_r2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_r2}, nullptr, nullptr, - nullptr, - 0}, + }, {"r3", nullptr, 4, @@ -233,8 +230,7 @@ static RegisterInfo g_register_infos[] = { {ehframe_r3, dwarf_r3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_r3}, nullptr, nullptr, - nullptr, - 0}, + }, {"r4", nullptr, 4, @@ -244,8 +240,7 @@ static RegisterInfo g_register_infos[] = { {ehframe_r4, dwarf_r4, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_r4}, nullptr, nullptr, - nullptr, - 0}, + }, {"r5", nullptr, 4, @@ -255,8 +250,7 @@ static RegisterInfo g_register_infos[] = { {ehframe_r5, dwarf_r5, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_r5}, nullptr, nullptr, - nullptr, - 0}, + }, {"r6", nullptr, 4, @@ -266,8 +260,7 @@ static RegisterInfo g_register_infos[] = { {ehframe_r6, dwarf_r6, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_r6}, nullptr, nullptr, - nullptr, - 0}, + }, {"r7", nullptr, 4, @@ -278,8 +271,7 @@ static RegisterInfo g_register_infos[] = { gpr_r7}, nullptr, nullptr, - nullptr, - 0}, + }, {"r8", nullptr, 4, @@ -289,8 +281,7 @@ static RegisterInfo g_register_infos[] = { {ehframe_r8, dwarf_r8, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_r8}, nullptr, nullptr, - nullptr, - 0}, + }, {"r9", nullptr, 4, @@ -300,8 +291,7 @@ static RegisterInfo g_register_infos[] = { {ehframe_r9, dwarf_r9, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_r9}, nullptr, nullptr, - nullptr, - 0}, + }, {"r10", nullptr, 4, @@ -312,8 +302,7 @@ static RegisterInfo g_register_infos[] = { gpr_r10}, nullptr, nullptr, - nullptr, - 0}, + }, {"r11", nullptr, 4, @@ -324,8 +313,7 @@ static RegisterInfo g_register_infos[] = { gpr_r11}, nullptr, nullptr, - nullptr, - 0}, + }, {"r12", nullptr, 4, @@ -336,8 +324,7 @@ static RegisterInfo g_register_infos[] = { gpr_r12}, nullptr, nullptr, - nullptr, - 0}, + }, {"sp", "r13", 4, @@ -348,8 +335,7 @@ static RegisterInfo g_register_infos[] = { gpr_sp}, nullptr, nullptr, - nullptr, - 0}, + }, {"lr", "r14", 4, @@ -360,8 +346,7 @@ static RegisterInfo g_register_infos[] = { gpr_lr}, nullptr, nullptr, - nullptr, - 0}, + }, {"pc", "r15", 4, @@ -372,8 +357,7 @@ static RegisterInfo g_register_infos[] = { gpr_pc}, nullptr, nullptr, - nullptr, - 0}, + }, {"cpsr", "psr", 4, @@ -384,8 +368,7 @@ static RegisterInfo g_register_infos[] = { gpr_cpsr}, nullptr, nullptr, - nullptr, - 0}, + }, {"s0", nullptr, @@ -397,8 +380,7 @@ static RegisterInfo g_register_infos[] = { fpu_s0}, nullptr, nullptr, - nullptr, - 0}, + }, {"s1", nullptr, 4, @@ -409,8 +391,7 @@ static RegisterInfo g_register_infos[] = { fpu_s1}, nullptr, nullptr, - nullptr, - 0}, + }, {"s2", nullptr, 4, @@ -421,8 +402,7 @@ static RegisterInfo g_register_infos[] = { fpu_s2}, nullptr, nullptr, - nullptr, - 0}, + }, {"s3", nullptr, 4, @@ -433,8 +413,7 @@ static RegisterInfo g_register_infos[] = { fpu_s3}, nullptr, nullptr, - nullptr, - 0}, + }, {"s4", nullptr, 4, @@ -445,8 +424,7 @@ static RegisterInfo g_register_infos[] = { fpu_s4}, nullptr, nullptr, - nullptr, - 0}, + }, {"s5", nullptr, 4, @@ -457,8 +435,7 @@ static RegisterInfo g_register_infos[] = { fpu_s5}, nullptr, nullptr, - nullptr, - 0}, + }, {"s6", nullptr, 4, @@ -469,8 +446,7 @@ static RegisterInfo g_register_infos[] = { fpu_s6}, nullptr, nullptr, - nullptr, - 0}, + }, {"s7", nullptr, 4, @@ -481,8 +457,7 @@ static RegisterInfo g_register_infos[] = { fpu_s7}, nullptr, nullptr, - nullptr, - 0}, + }, {"s8", nullptr, 4, @@ -493,8 +468,7 @@ static RegisterInfo g_register_infos[] = { fpu_s8}, nullptr, nullptr, - nullptr, - 0}, + }, {"s9", nullptr, 4, @@ -505,8 +479,7 @@ static RegisterInfo g_register_infos[] = { fpu_s9}, nullptr, nullptr, - nullptr, - 0}, + }, {"s10", nullptr, 4, @@ -517,8 +490,7 @@ static RegisterInfo g_register_infos[] = { fpu_s10}, nullptr, nullptr, - nullptr, - 0}, + }, {"s11", nullptr, 4, @@ -529,8 +501,7 @@ static RegisterInfo g_register_infos[] = { fpu_s11}, nullptr, nullptr, - nullptr, - 0}, + }, {"s12", nullptr, 4, @@ -541,8 +512,7 @@ static RegisterInfo g_register_infos[] = { fpu_s12}, nullptr, nullptr, - nullptr, - 0}, + }, {"s13", nullptr, 4, @@ -553,8 +523,7 @@ static RegisterInfo g_register_infos[] = { fpu_s13}, nullptr, nullptr, - nullptr, - 0}, + }, {"s14", nullptr, 4, @@ -565,8 +534,7 @@ static RegisterInfo g_register_infos[] = { fpu_s14}, nullptr, nullptr, - nullptr, - 0}, + }, {"s15", nullptr, 4, @@ -577,8 +545,7 @@ static RegisterInfo g_register_infos[] = { fpu_s15}, nullptr, nullptr, - nullptr, - 0}, + }, {"s16", nullptr, 4, @@ -589,8 +556,7 @@ static RegisterInfo g_register_infos[] = { fpu_s16}, nullptr, nullptr, - nullptr, - 0}, + }, {"s17", nullptr, 4, @@ -601,8 +567,7 @@ static RegisterInfo g_register_infos[] = { fpu_s17}, nullptr, nullptr, - nullptr, - 0}, + }, {"s18", nullptr, 4, @@ -613,8 +578,7 @@ static RegisterInfo g_register_infos[] = { fpu_s18}, nullptr, nullptr, - nullptr, - 0}, + }, {"s19", nullptr, 4, @@ -625,8 +589,7 @@ static RegisterInfo g_register_infos[] = { fpu_s19}, nullptr, nullptr, - nullptr, - 0}, + }, {"s20", nullptr, 4, @@ -637,8 +600,7 @@ static RegisterInfo g_register_infos[] = { fpu_s20}, nullptr, nullptr, - nullptr, - 0}, + }, {"s21", nullptr, 4, @@ -649,8 +611,7 @@ static RegisterInfo g_register_infos[] = { fpu_s21}, nullptr, nullptr, - nullptr, - 0}, + }, {"s22", nullptr, 4, @@ -661,8 +622,7 @@ static RegisterInfo g_register_infos[] = { fpu_s22}, nullptr, nullptr, - nullptr, - 0}, + }, {"s23", nullptr, 4, @@ -673,8 +633,7 @@ static RegisterInfo g_register_infos[] = { fpu_s23}, nullptr, nullptr, - nullptr, - 0}, + }, {"s24", nullptr, 4, @@ -685,8 +644,7 @@ static RegisterInfo g_register_infos[] = { fpu_s24}, nullptr, nullptr, - nullptr, - 0}, + }, {"s25", nullptr, 4, @@ -697,8 +655,7 @@ static RegisterInfo g_register_infos[] = { fpu_s25}, nullptr, nullptr, - nullptr, - 0}, + }, {"s26", nullptr, 4, @@ -709,8 +666,7 @@ static RegisterInfo g_register_infos[] = { fpu_s26}, nullptr, nullptr, - nullptr, - 0}, + }, {"s27", nullptr, 4, @@ -721,8 +677,7 @@ static RegisterInfo g_register_infos[] = { fpu_s27}, nullptr, nullptr, - nullptr, - 0}, + }, {"s28", nullptr, 4, @@ -733,8 +688,7 @@ static RegisterInfo g_register_infos[] = { fpu_s28}, nullptr, nullptr, - nullptr, - 0}, + }, {"s29", nullptr, 4, @@ -745,8 +699,7 @@ static RegisterInfo g_register_infos[] = { fpu_s29}, nullptr, nullptr, - nullptr, - 0}, + }, {"s30", nullptr, 4, @@ -757,8 +710,7 @@ static RegisterInfo g_register_infos[] = { fpu_s30}, nullptr, nullptr, - nullptr, - 0}, + }, {"s31", nullptr, 4, @@ -769,8 +721,7 @@ static RegisterInfo g_register_infos[] = { fpu_s31}, nullptr, nullptr, - nullptr, - 0}, + }, {"fpscr", nullptr, 4, @@ -781,8 +732,7 @@ static RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM, fpu_fpscr}, nullptr, nullptr, - nullptr, - 0}, + }, {"exception", nullptr, @@ -794,8 +744,7 @@ static RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM, exc_exception}, nullptr, nullptr, - nullptr, - 0}, + }, {"fsr", nullptr, 4, @@ -806,8 +755,7 @@ static RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM, exc_fsr}, nullptr, nullptr, - nullptr, - 0}, + }, {"far", nullptr, 4, @@ -818,8 +766,7 @@ static RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM, exc_far}, nullptr, nullptr, - nullptr, - 0}, + }, {DEFINE_DBG(bvr, 0)}, {DEFINE_DBG(bvr, 1)}, diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_arm64.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_arm64.cpp index b98b2f35c23e..50f710e26815 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_arm64.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_arm64.cpp @@ -59,7 +59,7 @@ using namespace lldb_private; {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \ LLDB_INVALID_REGNUM }, \ - NULL, NULL, NULL, 0 + NULL, NULL #define REG_CONTEXT_SIZE \ (sizeof(RegisterContextDarwin_arm64::GPR) + \ sizeof(RegisterContextDarwin_arm64::FPU) + \ diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_i386.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_i386.cpp index 95f8132a990c..5f56e6f1636a 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_i386.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_i386.cpp @@ -154,7 +154,7 @@ enum { {LLDB_INVALID_REGNUM, dwarf_##reg##i, \ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \ fpu_##reg##i }, \ - nullptr, nullptr, nullptr, 0 + nullptr, nullptr, #define DEFINE_EXC(reg) \ #reg, NULL, sizeof(((RegisterContextDarwin_i386::EXC *) NULL)->reg), \ @@ -175,184 +175,158 @@ static RegisterInfo g_register_infos[] = { gpr_eax}, nullptr, nullptr, - nullptr, - 0}, + }, {DEFINE_GPR(ebx, nullptr), {ehframe_ebx, dwarf_ebx, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_ebx}, nullptr, nullptr, - nullptr, - 0}, + }, {DEFINE_GPR(ecx, nullptr), {ehframe_ecx, dwarf_ecx, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_ecx}, nullptr, nullptr, - nullptr, - 0}, + }, {DEFINE_GPR(edx, nullptr), {ehframe_edx, dwarf_edx, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_edx}, nullptr, nullptr, - nullptr, - 0}, + }, {DEFINE_GPR(edi, nullptr), {ehframe_edi, dwarf_edi, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_edi}, nullptr, nullptr, - nullptr, - 0}, + }, {DEFINE_GPR(esi, nullptr), {ehframe_esi, dwarf_esi, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_esi}, nullptr, nullptr, - nullptr, - 0}, + }, {DEFINE_GPR(ebp, "fp"), {ehframe_ebp, dwarf_ebp, LLDB_REGNUM_GENERIC_FP, LLDB_INVALID_REGNUM, gpr_ebp}, nullptr, nullptr, - nullptr, - 0}, + }, {DEFINE_GPR(esp, "sp"), {ehframe_esp, dwarf_esp, LLDB_REGNUM_GENERIC_SP, LLDB_INVALID_REGNUM, gpr_esp}, nullptr, nullptr, - nullptr, - 0}, + }, {DEFINE_GPR(ss, nullptr), {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_ss}, nullptr, nullptr, - nullptr, - 0}, + }, {DEFINE_GPR(eflags, "flags"), {ehframe_eflags, dwarf_eflags, LLDB_REGNUM_GENERIC_FLAGS, LLDB_INVALID_REGNUM, gpr_eflags}, nullptr, nullptr, - nullptr, - 0}, + }, {DEFINE_GPR(eip, "pc"), {ehframe_eip, dwarf_eip, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_REGNUM, gpr_eip}, nullptr, nullptr, - nullptr, - 0}, + }, {DEFINE_GPR(cs, nullptr), {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_cs}, nullptr, nullptr, - nullptr, - 0}, + }, {DEFINE_GPR(ds, nullptr), {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_ds}, nullptr, nullptr, - nullptr, - 0}, + }, {DEFINE_GPR(es, nullptr), {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_es}, nullptr, nullptr, - nullptr, - 0}, + }, {DEFINE_GPR(fs, nullptr), {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_fs}, nullptr, nullptr, - nullptr, - 0}, + }, {DEFINE_GPR(gs, nullptr), {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_gs}, nullptr, nullptr, - nullptr, - 0}, + }, {DEFINE_FPU_UINT(fcw), {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_fcw}, nullptr, nullptr, - nullptr, - 0}, + }, {DEFINE_FPU_UINT(fsw), {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_fsw}, nullptr, nullptr, - nullptr, - 0}, + }, {DEFINE_FPU_UINT(ftw), {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_ftw}, nullptr, nullptr, - nullptr, - 0}, + }, {DEFINE_FPU_UINT(fop), {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_fop}, nullptr, nullptr, - nullptr, - 0}, + }, {DEFINE_FPU_UINT(ip), {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_ip}, nullptr, nullptr, - nullptr, - 0}, + }, {DEFINE_FPU_UINT(cs), {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_cs}, nullptr, nullptr, - nullptr, - 0}, + }, {DEFINE_FPU_UINT(dp), {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_dp}, nullptr, nullptr, - nullptr, - 0}, + }, {DEFINE_FPU_UINT(ds), {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_ds}, nullptr, nullptr, - nullptr, - 0}, + }, {DEFINE_FPU_UINT(mxcsr), {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_mxcsr}, nullptr, nullptr, - nullptr, - 0}, + }, {DEFINE_FPU_UINT(mxcsrmask), {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_mxcsrmask}, nullptr, nullptr, - nullptr, - 0}, + }, {DEFINE_FPU_VECT(stmm, 0)}, {DEFINE_FPU_VECT(stmm, 1)}, {DEFINE_FPU_VECT(stmm, 2)}, @@ -375,22 +349,19 @@ static RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM, exc_trapno}, nullptr, nullptr, - nullptr, - 0}, + }, {DEFINE_EXC(err), {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, exc_err}, nullptr, nullptr, - nullptr, - 0}, + }, {DEFINE_EXC(faultvaddr), {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, exc_faultvaddr}, nullptr, nullptr, - nullptr, - 0}}; + }}; static size_t k_num_register_infos = llvm::array_lengthof(g_register_infos); diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_x86_64.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_x86_64.cpp index 03e5ea424e39..567df8fc980c 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_x86_64.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_x86_64.cpp @@ -172,7 +172,7 @@ enum ehframe_dwarf_regnums { {ehframe_dwarf_fpu_##reg##i, \ ehframe_dwarf_fpu_##reg##i, LLDB_INVALID_REGNUM, \ LLDB_INVALID_REGNUM, fpu_##reg##i }, \ - nullptr, nullptr, nullptr, 0 + nullptr, nullptr, #define DEFINE_EXC(reg) \ #reg, NULL, sizeof(((RegisterContextDarwin_x86_64::EXC *) NULL)->reg), \ EXC_OFFSET(reg), eEncodingUint, eFormatHex @@ -194,219 +194,188 @@ static RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM, gpr_rax}, nullptr, nullptr, - nullptr, - 0}, + }, {DEFINE_GPR(rbx, nullptr), {ehframe_dwarf_gpr_rbx, ehframe_dwarf_gpr_rbx, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_rbx}, nullptr, nullptr, - nullptr, - 0}, + }, {DEFINE_GPR(rcx, nullptr), {ehframe_dwarf_gpr_rcx, ehframe_dwarf_gpr_rcx, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_rcx}, nullptr, nullptr, - nullptr, - 0}, + }, {DEFINE_GPR(rdx, nullptr), {ehframe_dwarf_gpr_rdx, ehframe_dwarf_gpr_rdx, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_rdx}, nullptr, nullptr, - nullptr, - 0}, + }, {DEFINE_GPR(rdi, nullptr), {ehframe_dwarf_gpr_rdi, ehframe_dwarf_gpr_rdi, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_rdi}, nullptr, nullptr, - nullptr, - 0}, + }, {DEFINE_GPR(rsi, nullptr), {ehframe_dwarf_gpr_rsi, ehframe_dwarf_gpr_rsi, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_rsi}, nullptr, nullptr, - nullptr, - 0}, + }, {DEFINE_GPR(rbp, "fp"), {ehframe_dwarf_gpr_rbp, ehframe_dwarf_gpr_rbp, LLDB_REGNUM_GENERIC_FP, LLDB_INVALID_REGNUM, gpr_rbp}, nullptr, nullptr, - nullptr, - 0}, + }, {DEFINE_GPR(rsp, "sp"), {ehframe_dwarf_gpr_rsp, ehframe_dwarf_gpr_rsp, LLDB_REGNUM_GENERIC_SP, LLDB_INVALID_REGNUM, gpr_rsp}, nullptr, nullptr, - nullptr, - 0}, + }, {DEFINE_GPR(r8, nullptr), {ehframe_dwarf_gpr_r8, ehframe_dwarf_gpr_r8, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_r8}, nullptr, nullptr, - nullptr, - 0}, + }, {DEFINE_GPR(r9, nullptr), {ehframe_dwarf_gpr_r9, ehframe_dwarf_gpr_r9, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_r9}, nullptr, nullptr, - nullptr, - 0}, + }, {DEFINE_GPR(r10, nullptr), {ehframe_dwarf_gpr_r10, ehframe_dwarf_gpr_r10, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_r10}, nullptr, nullptr, - nullptr, - 0}, + }, {DEFINE_GPR(r11, nullptr), {ehframe_dwarf_gpr_r11, ehframe_dwarf_gpr_r11, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_r11}, nullptr, nullptr, - nullptr, - 0}, + }, {DEFINE_GPR(r12, nullptr), {ehframe_dwarf_gpr_r12, ehframe_dwarf_gpr_r12, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_r12}, nullptr, nullptr, - nullptr, - 0}, + }, {DEFINE_GPR(r13, nullptr), {ehframe_dwarf_gpr_r13, ehframe_dwarf_gpr_r13, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_r13}, nullptr, nullptr, - nullptr, - 0}, + }, {DEFINE_GPR(r14, nullptr), {ehframe_dwarf_gpr_r14, ehframe_dwarf_gpr_r14, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_r14}, nullptr, nullptr, - nullptr, - 0}, + }, {DEFINE_GPR(r15, nullptr), {ehframe_dwarf_gpr_r15, ehframe_dwarf_gpr_r15, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_r15}, nullptr, nullptr, - nullptr, - 0}, + }, {DEFINE_GPR(rip, "pc"), {ehframe_dwarf_gpr_rip, ehframe_dwarf_gpr_rip, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_REGNUM, gpr_rip}, nullptr, nullptr, - nullptr, - 0}, + }, {DEFINE_GPR(rflags, "flags"), {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_REGNUM_GENERIC_FLAGS, LLDB_INVALID_REGNUM, gpr_rflags}, nullptr, nullptr, - nullptr, - 0}, + }, {DEFINE_GPR(cs, nullptr), {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_cs}, nullptr, nullptr, - nullptr, - 0}, + }, {DEFINE_GPR(fs, nullptr), {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_fs}, nullptr, nullptr, - nullptr, - 0}, + }, {DEFINE_GPR(gs, nullptr), {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_gs}, nullptr, nullptr, - nullptr, - 0}, + }, {DEFINE_FPU_UINT(fcw), {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_fcw}, nullptr, nullptr, - nullptr, - 0}, + }, {DEFINE_FPU_UINT(fsw), {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_fsw}, nullptr, nullptr, - nullptr, - 0}, + }, {DEFINE_FPU_UINT(ftw), {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_ftw}, nullptr, nullptr, - nullptr, - 0}, + }, {DEFINE_FPU_UINT(fop), {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_fop}, nullptr, nullptr, - nullptr, - 0}, + }, {DEFINE_FPU_UINT(ip), {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_ip}, nullptr, nullptr, - nullptr, - 0}, + }, {DEFINE_FPU_UINT(cs), {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_cs}, nullptr, nullptr, - nullptr, - 0}, + }, {DEFINE_FPU_UINT(dp), {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_dp}, nullptr, nullptr, - nullptr, - 0}, + }, {DEFINE_FPU_UINT(ds), {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_ds}, nullptr, nullptr, - nullptr, - 0}, + }, {DEFINE_FPU_UINT(mxcsr), {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_mxcsr}, nullptr, nullptr, - nullptr, - 0}, + }, {DEFINE_FPU_UINT(mxcsrmask), {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_mxcsrmask}, nullptr, nullptr, - nullptr, - 0}, + }, {DEFINE_FPU_VECT(stmm, 0)}, {DEFINE_FPU_VECT(stmm, 1)}, {DEFINE_FPU_VECT(stmm, 2)}, @@ -437,22 +406,19 @@ static RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM, exc_trapno}, nullptr, nullptr, - nullptr, - 0}, + }, {DEFINE_EXC(err), {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, exc_err}, nullptr, nullptr, - nullptr, - 0}, + }, {DEFINE_EXC(faultvaddr), {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, exc_faultvaddr}, nullptr, nullptr, - nullptr, - 0}}; + }}; static size_t k_num_register_infos = llvm::array_lengthof(g_register_infos); diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_mips64.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_mips64.cpp index 0c5d34f345db..7b4c7be21f74 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_mips64.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_mips64.cpp @@ -14,27 +14,53 @@ using namespace lldb_private; using namespace lldb; -static const uint32_t g_gpr_regnums[] = { - gpr_zero_mips64, gpr_r1_mips64, gpr_r2_mips64, gpr_r3_mips64, - gpr_r4_mips64, gpr_r5_mips64, gpr_r6_mips64, gpr_r7_mips64, - gpr_r8_mips64, gpr_r9_mips64, gpr_r10_mips64, gpr_r11_mips64, - gpr_r12_mips64, gpr_r13_mips64, gpr_r14_mips64, gpr_r15_mips64, - gpr_r16_mips64, gpr_r17_mips64, gpr_r18_mips64, gpr_r19_mips64, - gpr_r20_mips64, gpr_r21_mips64, gpr_r22_mips64, gpr_r23_mips64, - gpr_r24_mips64, gpr_r25_mips64, gpr_r26_mips64, gpr_r27_mips64, - gpr_gp_mips64, gpr_sp_mips64, gpr_r30_mips64, gpr_ra_mips64, - gpr_sr_mips64, gpr_mullo_mips64, gpr_mulhi_mips64, gpr_badvaddr_mips64, - gpr_cause_mips64, gpr_pc_mips64, gpr_ic_mips64, gpr_dummy_mips64}; +static const uint32_t g_gp_regnums_mips64[] = { + gpr_zero_mips64, gpr_r1_mips64, gpr_r2_mips64, gpr_r3_mips64, + gpr_r4_mips64, gpr_r5_mips64, gpr_r6_mips64, gpr_r7_mips64, + gpr_r8_mips64, gpr_r9_mips64, gpr_r10_mips64, gpr_r11_mips64, + gpr_r12_mips64, gpr_r13_mips64, gpr_r14_mips64, gpr_r15_mips64, + gpr_r16_mips64, gpr_r17_mips64, gpr_r18_mips64, gpr_r19_mips64, + gpr_r20_mips64, gpr_r21_mips64, gpr_r22_mips64, gpr_r23_mips64, + gpr_r24_mips64, gpr_r25_mips64, gpr_r26_mips64, gpr_r27_mips64, + gpr_gp_mips64, gpr_sp_mips64, gpr_r30_mips64, gpr_ra_mips64, + gpr_sr_mips64, gpr_mullo_mips64, gpr_mulhi_mips64, gpr_badvaddr_mips64, + gpr_cause_mips64, gpr_pc_mips64, gpr_ic_mips64, gpr_dummy_mips64, + LLDB_INVALID_REGNUM // register sets need to end with this flag +}; + +static_assert((sizeof(g_gp_regnums_mips64) / sizeof(g_gp_regnums_mips64[0])) - + 1 == + k_num_gpr_registers_mips64, + "g_gp_regnums_mips64 has wrong number of register infos"); + +const uint32_t g_fp_regnums_mips64[] = { + fpr_f0_mips64, fpr_f1_mips64, fpr_f2_mips64, fpr_f3_mips64, + fpr_f4_mips64, fpr_f5_mips64, fpr_f6_mips64, fpr_f7_mips64, + fpr_f8_mips64, fpr_f9_mips64, fpr_f10_mips64, fpr_f11_mips64, + fpr_f12_mips64, fpr_f13_mips64, fpr_f14_mips64, fpr_f15_mips64, + fpr_f16_mips64, fpr_f17_mips64, fpr_f18_mips64, fpr_f19_mips64, + fpr_f20_mips64, fpr_f21_mips64, fpr_f22_mips64, fpr_f23_mips64, + fpr_f24_mips64, fpr_f25_mips64, fpr_f26_mips64, fpr_f27_mips64, + fpr_f28_mips64, fpr_f29_mips64, fpr_f30_mips64, fpr_f31_mips64, + fpr_fcsr_mips64, fpr_fir_mips64, + LLDB_INVALID_REGNUM // register sets need to end with this flag +}; + +static_assert((sizeof(g_fp_regnums_mips64) / sizeof(g_fp_regnums_mips64[0])) - + 1 == + k_num_fpr_registers_mips64, + "g_fp_regnums_mips64 has wrong number of register infos"); // Number of register sets provided by this context. -constexpr size_t k_num_register_sets = 1; +constexpr size_t k_num_register_sets = 2; static const RegisterSet g_reg_sets_mips64[k_num_register_sets] = { {"General Purpose Registers", "gpr", k_num_gpr_registers_mips64, - g_gpr_regnums}, + g_gp_regnums_mips64}, + {"Floating Point Registers", "fpu", k_num_fpr_registers_mips64, + g_fp_regnums_mips64}, }; - // http://svnweb.freebsd.org/base/head/sys/mips/include/regnum.h typedef struct _GPR { uint64_t zero; @@ -79,6 +105,43 @@ typedef struct _GPR { uint64_t dummy; } GPR_freebsd_mips; +typedef struct _FPR { + uint64_t f0; + uint64_t f1; + uint64_t f2; + uint64_t f3; + uint64_t f4; + uint64_t f5; + uint64_t f6; + uint64_t f7; + uint64_t f8; + uint64_t f9; + uint64_t f10; + uint64_t f11; + uint64_t f12; + uint64_t f13; + uint64_t f14; + uint64_t f15; + uint64_t f16; + uint64_t f17; + uint64_t f18; + uint64_t f19; + uint64_t f20; + uint64_t f21; + uint64_t f22; + uint64_t f23; + uint64_t f24; + uint64_t f25; + uint64_t f26; + uint64_t f27; + uint64_t f28; + uint64_t f29; + uint64_t f30; + uint64_t f31; + uint64_t fcsr; + uint64_t fir; +} FPR_freebsd_mips; + // Include RegisterInfos_mips64 to declare our g_register_infos_mips64 // structure. #define DECLARE_REGISTER_INFOS_MIPS64_STRUCT @@ -95,14 +158,13 @@ size_t RegisterContextFreeBSD_mips64::GetGPRSize() const { const RegisterSet * RegisterContextFreeBSD_mips64::GetRegisterSet(size_t set) const { - // Check if RegisterSet is available - if (set < k_num_register_sets) - return &g_reg_sets_mips64[set]; - return nullptr; + // Check if RegisterSet is available + if (set < k_num_register_sets) + return &g_reg_sets_mips64[set]; + return nullptr; } -size_t -RegisterContextFreeBSD_mips64::GetRegisterSetCount() const { +size_t RegisterContextFreeBSD_mips64::GetRegisterSetCount() const { return k_num_register_sets; } diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextLinux_i386.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextLinux_i386.cpp index 518dc273faf4..39bec20649a4 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextLinux_i386.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextLinux_i386.cpp @@ -89,19 +89,18 @@ struct UserArea { RegisterContextLinux_i386::RegisterContextLinux_i386( const ArchSpec &target_arch) : RegisterInfoInterface(target_arch) { - RegisterInfo orig_ax = {"orig_eax", - nullptr, - sizeof(((GPR *)nullptr)->orig_eax), - (LLVM_EXTENSION offsetof(GPR, orig_eax)), - eEncodingUint, - eFormatHex, - {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, - LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, - LLDB_INVALID_REGNUM}, - nullptr, - nullptr, - nullptr, - 0}; + RegisterInfo orig_ax = { + "orig_eax", + nullptr, + sizeof(((GPR *)nullptr)->orig_eax), + (LLVM_EXTENSION offsetof(GPR, orig_eax)), + eEncodingUint, + eFormatHex, + {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + }; d_register_infos.push_back(orig_ax); } diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextLinux_x86_64.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextLinux_x86_64.cpp index f9d4e23fcde2..20b8d74f8c0d 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextLinux_x86_64.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextLinux_x86_64.cpp @@ -156,19 +156,18 @@ RegisterContextLinux_x86_64::RegisterContextLinux_x86_64( m_register_info_p(GetRegisterInfoPtr(target_arch)), m_register_info_count(GetRegisterInfoCount(target_arch)), m_user_register_count(GetUserRegisterInfoCount(target_arch)) { - RegisterInfo orig_ax = {"orig_rax", - nullptr, - sizeof(((GPR *)nullptr)->orig_rax), - (LLVM_EXTENSION offsetof(GPR, orig_rax)), - eEncodingUint, - eFormatHex, - {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, - LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, - LLDB_INVALID_REGNUM}, - nullptr, - nullptr, - nullptr, - 0}; + RegisterInfo orig_ax = { + "orig_rax", + nullptr, + sizeof(((GPR *)nullptr)->orig_rax), + (LLVM_EXTENSION offsetof(GPR, orig_rax)), + eEncodingUint, + eFormatHex, + {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + }; d_register_infos.push_back(orig_ax); } diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextMemory.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextMemory.cpp index c55ffebb03e7..49a4c8669022 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextMemory.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextMemory.cpp @@ -8,7 +8,6 @@ #include "RegisterContextMemory.h" -#include "DynamicRegisterInfo.h" #include "lldb/Target/Process.h" #include "lldb/Target/Thread.h" #include "lldb/Utility/DataBufferHeap.h" diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextMemory.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextMemory.h index 764ee9b97211..c3b9ec72ca22 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextMemory.h +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextMemory.h @@ -11,17 +11,16 @@ #include <vector> +#include "lldb/Target/DynamicRegisterInfo.h" #include "lldb/Target/RegisterContext.h" #include "lldb/Utility/DataExtractor.h" #include "lldb/lldb-private.h" -class DynamicRegisterInfo; - class RegisterContextMemory : public lldb_private::RegisterContext { public: RegisterContextMemory(lldb_private::Thread &thread, uint32_t concrete_frame_idx, - DynamicRegisterInfo ®_info, + lldb_private::DynamicRegisterInfo ®_info, lldb::addr_t reg_data_addr); ~RegisterContextMemory() override; @@ -60,7 +59,7 @@ public: protected: void SetAllRegisterValid(bool b); - DynamicRegisterInfo &m_reg_infos; + lldb_private::DynamicRegisterInfo &m_reg_infos; std::vector<bool> m_reg_valid; lldb_private::DataExtractor m_reg_data; lldb::addr_t m_reg_data_addr; // If this is valid, then we have a register diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextWindows_i386.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextWindows_i386.cpp index 11556e802e33..066d50d9c149 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextWindows_i386.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextWindows_i386.cpp @@ -41,7 +41,6 @@ typedef struct _GPR { #reg, alt, sizeof(((GPR *)nullptr)->reg), GPR_OFFSET(reg), eEncodingUint, \ eFormatHex, \ {kind1, kind2, kind3, kind4, lldb_##reg##_i386 }, nullptr, nullptr, \ - nullptr, 0 \ } // clang-format off diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextWindows_x86_64.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextWindows_x86_64.cpp index 4ffc4d25781c..a35ccace5d5b 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextWindows_x86_64.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextWindows_x86_64.cpp @@ -49,7 +49,6 @@ typedef struct _GPR { #reg, alt, sizeof(((GPR *)nullptr)->reg), GPR_OFFSET(reg), eEncodingUint, \ eFormatHex, \ {kind1, kind2, kind3, kind4, lldb_##reg##_x86_64 }, nullptr, nullptr, \ - nullptr, 0 \ } typedef struct _FPReg { @@ -80,7 +79,7 @@ typedef struct _FPReg { eEncodingUint, eFormatVectorOfUInt64, \ {dwarf_##reg##_x86_64, dwarf_##reg##_x86_64, LLDB_INVALID_REGNUM, \ LLDB_INVALID_REGNUM, lldb_##reg##_x86_64 }, \ - nullptr, nullptr, nullptr, 0 \ + nullptr, nullptr, \ } // clang-format off @@ -89,22 +88,22 @@ static RegisterInfo g_register_infos_x86_64[] = { // =========================== ================== ================ ========================= ==================== DEFINE_GPR(rax, nullptr, dwarf_rax_x86_64, dwarf_rax_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), DEFINE_GPR(rbx, nullptr, dwarf_rbx_x86_64, dwarf_rbx_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), - DEFINE_GPR(rcx, "arg4", dwarf_rcx_x86_64, dwarf_rcx_x86_64, LLDB_REGNUM_GENERIC_ARG4, LLDB_INVALID_REGNUM), - DEFINE_GPR(rdx, "arg3", dwarf_rdx_x86_64, dwarf_rdx_x86_64, LLDB_REGNUM_GENERIC_ARG3, LLDB_INVALID_REGNUM), - DEFINE_GPR(rdi, "arg1", dwarf_rdi_x86_64, dwarf_rdi_x86_64, LLDB_REGNUM_GENERIC_ARG1, LLDB_INVALID_REGNUM), - DEFINE_GPR(rsi, "arg2", dwarf_rsi_x86_64, dwarf_rsi_x86_64, LLDB_REGNUM_GENERIC_ARG2, LLDB_INVALID_REGNUM), - DEFINE_GPR(rbp, "fp", dwarf_rbp_x86_64, dwarf_rbp_x86_64, LLDB_REGNUM_GENERIC_FP, LLDB_INVALID_REGNUM), - DEFINE_GPR(rsp, "sp", dwarf_rsp_x86_64, dwarf_rsp_x86_64, LLDB_REGNUM_GENERIC_SP, LLDB_INVALID_REGNUM), - DEFINE_GPR(r8, "arg5", dwarf_r8_x86_64, dwarf_r8_x86_64, LLDB_REGNUM_GENERIC_ARG5, LLDB_INVALID_REGNUM), - DEFINE_GPR(r9, "arg6", dwarf_r9_x86_64, dwarf_r9_x86_64, LLDB_REGNUM_GENERIC_ARG6, LLDB_INVALID_REGNUM), + DEFINE_GPR(rcx, nullptr, dwarf_rcx_x86_64, dwarf_rcx_x86_64, LLDB_REGNUM_GENERIC_ARG4, LLDB_INVALID_REGNUM), + DEFINE_GPR(rdx, nullptr, dwarf_rdx_x86_64, dwarf_rdx_x86_64, LLDB_REGNUM_GENERIC_ARG3, LLDB_INVALID_REGNUM), + DEFINE_GPR(rdi, nullptr, dwarf_rdi_x86_64, dwarf_rdi_x86_64, LLDB_REGNUM_GENERIC_ARG1, LLDB_INVALID_REGNUM), + DEFINE_GPR(rsi, nullptr, dwarf_rsi_x86_64, dwarf_rsi_x86_64, LLDB_REGNUM_GENERIC_ARG2, LLDB_INVALID_REGNUM), + DEFINE_GPR(rbp, nullptr, dwarf_rbp_x86_64, dwarf_rbp_x86_64, LLDB_REGNUM_GENERIC_FP, LLDB_INVALID_REGNUM), + DEFINE_GPR(rsp, nullptr, dwarf_rsp_x86_64, dwarf_rsp_x86_64, LLDB_REGNUM_GENERIC_SP, LLDB_INVALID_REGNUM), + DEFINE_GPR(r8, nullptr, dwarf_r8_x86_64, dwarf_r8_x86_64, LLDB_REGNUM_GENERIC_ARG5, LLDB_INVALID_REGNUM), + DEFINE_GPR(r9, nullptr, dwarf_r9_x86_64, dwarf_r9_x86_64, LLDB_REGNUM_GENERIC_ARG6, LLDB_INVALID_REGNUM), DEFINE_GPR(r10, nullptr, dwarf_r10_x86_64, dwarf_r10_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), DEFINE_GPR(r11, nullptr, dwarf_r11_x86_64, dwarf_r11_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), DEFINE_GPR(r12, nullptr, dwarf_r12_x86_64, dwarf_r12_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), DEFINE_GPR(r13, nullptr, dwarf_r13_x86_64, dwarf_r13_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), DEFINE_GPR(r14, nullptr, dwarf_r14_x86_64, dwarf_r14_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), DEFINE_GPR(r15, nullptr, dwarf_r15_x86_64, dwarf_r15_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), - DEFINE_GPR(rip, "pc", dwarf_rip_x86_64, dwarf_rip_x86_64, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_REGNUM), - DEFINE_GPR(rflags, "flags", dwarf_rflags_x86_64, dwarf_rflags_x86_64, LLDB_REGNUM_GENERIC_FLAGS, LLDB_INVALID_REGNUM), + DEFINE_GPR(rip, nullptr, dwarf_rip_x86_64, dwarf_rip_x86_64, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_REGNUM), + DEFINE_GPR(rflags, nullptr, dwarf_rflags_x86_64, dwarf_rflags_x86_64, LLDB_REGNUM_GENERIC_FLAGS, LLDB_INVALID_REGNUM), DEFINE_GPR(cs, nullptr, dwarf_cs_x86_64, dwarf_cs_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), DEFINE_GPR(fs, nullptr, dwarf_fs_x86_64, dwarf_fs_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), DEFINE_GPR(gs, nullptr, dwarf_gs_x86_64, dwarf_gs_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm.cpp index 63461f7ab2db..fd4c373e2cb1 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm.cpp @@ -38,7 +38,7 @@ using namespace lldb_private; {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \ dbg_##reg##i }, \ - NULL, NULL, NULL, 0 + NULL, NULL, #define REG_CONTEXT_SIZE \ (sizeof(RegisterInfoPOSIX_arm::GPR) + sizeof(RegisterInfoPOSIX_arm::FPU) + \ sizeof(RegisterInfoPOSIX_arm::EXC)) diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm64.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm64.cpp index b878534b39db..6c130be7b741 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm64.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm64.cpp @@ -60,7 +60,7 @@ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \ dbg_##reg##i }, \ - NULL, NULL, NULL, 0 + NULL, NULL, #define REG_CONTEXT_SIZE \ (sizeof(RegisterInfoPOSIX_arm64::GPR) + \ sizeof(RegisterInfoPOSIX_arm64::FPU) + \ diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_arm.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_arm.h index 4af0069eb6f3..ace2e5a9f68b 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_arm.h +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_arm.h @@ -254,39 +254,38 @@ static uint32_t g_s29_invalidates[] = {fpu_d14, fpu_q7, LLDB_INVALID_REGNUM}; static uint32_t g_s30_invalidates[] = {fpu_d15, fpu_q7, LLDB_INVALID_REGNUM}; static uint32_t g_s31_invalidates[] = {fpu_d15, fpu_q7, LLDB_INVALID_REGNUM}; -static uint32_t g_d0_contains[] = {fpu_s0, fpu_s1, LLDB_INVALID_REGNUM}; -static uint32_t g_d1_contains[] = {fpu_s2, fpu_s3, LLDB_INVALID_REGNUM}; -static uint32_t g_d2_contains[] = {fpu_s4, fpu_s5, LLDB_INVALID_REGNUM}; -static uint32_t g_d3_contains[] = {fpu_s6, fpu_s7, LLDB_INVALID_REGNUM}; -static uint32_t g_d4_contains[] = {fpu_s8, fpu_s9, LLDB_INVALID_REGNUM}; -static uint32_t g_d5_contains[] = {fpu_s10, fpu_s11, LLDB_INVALID_REGNUM}; -static uint32_t g_d6_contains[] = {fpu_s12, fpu_s13, LLDB_INVALID_REGNUM}; -static uint32_t g_d7_contains[] = {fpu_s14, fpu_s15, LLDB_INVALID_REGNUM}; -static uint32_t g_d8_contains[] = {fpu_s16, fpu_s17, LLDB_INVALID_REGNUM}; -static uint32_t g_d9_contains[] = {fpu_s18, fpu_s19, LLDB_INVALID_REGNUM}; -static uint32_t g_d10_contains[] = {fpu_s20, fpu_s21, LLDB_INVALID_REGNUM}; -static uint32_t g_d11_contains[] = {fpu_s22, fpu_s23, LLDB_INVALID_REGNUM}; -static uint32_t g_d12_contains[] = {fpu_s24, fpu_s25, LLDB_INVALID_REGNUM}; -static uint32_t g_d13_contains[] = {fpu_s26, fpu_s27, LLDB_INVALID_REGNUM}; -static uint32_t g_d14_contains[] = {fpu_s28, fpu_s29, LLDB_INVALID_REGNUM}; -static uint32_t g_d15_contains[] = {fpu_s30, fpu_s31, LLDB_INVALID_REGNUM}; - -static uint32_t g_d0_invalidates[] = {fpu_q0, LLDB_INVALID_REGNUM}; -static uint32_t g_d1_invalidates[] = {fpu_q0, LLDB_INVALID_REGNUM}; -static uint32_t g_d2_invalidates[] = {fpu_q1, LLDB_INVALID_REGNUM}; -static uint32_t g_d3_invalidates[] = {fpu_q1, LLDB_INVALID_REGNUM}; -static uint32_t g_d4_invalidates[] = {fpu_q2, LLDB_INVALID_REGNUM}; -static uint32_t g_d5_invalidates[] = {fpu_q2, LLDB_INVALID_REGNUM}; -static uint32_t g_d6_invalidates[] = {fpu_q3, LLDB_INVALID_REGNUM}; -static uint32_t g_d7_invalidates[] = {fpu_q3, LLDB_INVALID_REGNUM}; -static uint32_t g_d8_invalidates[] = {fpu_q4, LLDB_INVALID_REGNUM}; -static uint32_t g_d9_invalidates[] = {fpu_q4, LLDB_INVALID_REGNUM}; -static uint32_t g_d10_invalidates[] = {fpu_q5, LLDB_INVALID_REGNUM}; -static uint32_t g_d11_invalidates[] = {fpu_q5, LLDB_INVALID_REGNUM}; -static uint32_t g_d12_invalidates[] = {fpu_q6, LLDB_INVALID_REGNUM}; -static uint32_t g_d13_invalidates[] = {fpu_q6, LLDB_INVALID_REGNUM}; -static uint32_t g_d14_invalidates[] = {fpu_q7, LLDB_INVALID_REGNUM}; -static uint32_t g_d15_invalidates[] = {fpu_q7, LLDB_INVALID_REGNUM}; +static uint32_t g_d0_invalidates[] = {fpu_q0, fpu_s0, fpu_s1, + LLDB_INVALID_REGNUM}; +static uint32_t g_d1_invalidates[] = {fpu_q0, fpu_s2, fpu_s3, + LLDB_INVALID_REGNUM}; +static uint32_t g_d2_invalidates[] = {fpu_q1, fpu_s4, fpu_s5, + LLDB_INVALID_REGNUM}; +static uint32_t g_d3_invalidates[] = {fpu_q1, fpu_s6, fpu_s7, + LLDB_INVALID_REGNUM}; +static uint32_t g_d4_invalidates[] = {fpu_q2, fpu_s8, fpu_s9, + LLDB_INVALID_REGNUM}; +static uint32_t g_d5_invalidates[] = {fpu_q2, fpu_s10, fpu_s11, + LLDB_INVALID_REGNUM}; +static uint32_t g_d6_invalidates[] = {fpu_q3, fpu_s12, fpu_s13, + LLDB_INVALID_REGNUM}; +static uint32_t g_d7_invalidates[] = {fpu_q3, fpu_s14, fpu_s15, + LLDB_INVALID_REGNUM}; +static uint32_t g_d8_invalidates[] = {fpu_q4, fpu_s16, fpu_s17, + LLDB_INVALID_REGNUM}; +static uint32_t g_d9_invalidates[] = {fpu_q4, fpu_s18, fpu_s19, + LLDB_INVALID_REGNUM}; +static uint32_t g_d10_invalidates[] = {fpu_q5, fpu_s20, fpu_s21, + LLDB_INVALID_REGNUM}; +static uint32_t g_d11_invalidates[] = {fpu_q5, fpu_s22, fpu_s23, + LLDB_INVALID_REGNUM}; +static uint32_t g_d12_invalidates[] = {fpu_q6, fpu_s24, fpu_s25, + LLDB_INVALID_REGNUM}; +static uint32_t g_d13_invalidates[] = {fpu_q6, fpu_s26, fpu_s27, + LLDB_INVALID_REGNUM}; +static uint32_t g_d14_invalidates[] = {fpu_q7, fpu_s28, fpu_s29, + LLDB_INVALID_REGNUM}; +static uint32_t g_d15_invalidates[] = {fpu_q7, fpu_s30, fpu_s31, + LLDB_INVALID_REGNUM}; static uint32_t g_d16_invalidates[] = {fpu_q8, LLDB_INVALID_REGNUM}; static uint32_t g_d17_invalidates[] = {fpu_q8, LLDB_INVALID_REGNUM}; static uint32_t g_d18_invalidates[] = {fpu_q9, LLDB_INVALID_REGNUM}; @@ -304,30 +303,64 @@ static uint32_t g_d29_invalidates[] = {fpu_q14, LLDB_INVALID_REGNUM}; static uint32_t g_d30_invalidates[] = {fpu_q15, LLDB_INVALID_REGNUM}; static uint32_t g_d31_invalidates[] = {fpu_q15, LLDB_INVALID_REGNUM}; -static uint32_t g_q0_contains[] = { +static uint32_t g_q0_invalidates[] = { fpu_d0, fpu_d1, fpu_s0, fpu_s1, fpu_s2, fpu_s3, LLDB_INVALID_REGNUM}; -static uint32_t g_q1_contains[] = { +static uint32_t g_q1_invalidates[] = { fpu_d2, fpu_d3, fpu_s4, fpu_s5, fpu_s6, fpu_s7, LLDB_INVALID_REGNUM}; -static uint32_t g_q2_contains[] = { +static uint32_t g_q2_invalidates[] = { fpu_d4, fpu_d5, fpu_s8, fpu_s9, fpu_s10, fpu_s11, LLDB_INVALID_REGNUM}; -static uint32_t g_q3_contains[] = { +static uint32_t g_q3_invalidates[] = { fpu_d6, fpu_d7, fpu_s12, fpu_s13, fpu_s14, fpu_s15, LLDB_INVALID_REGNUM}; -static uint32_t g_q4_contains[] = { +static uint32_t g_q4_invalidates[] = { fpu_d8, fpu_d9, fpu_s16, fpu_s17, fpu_s18, fpu_s19, LLDB_INVALID_REGNUM}; -static uint32_t g_q5_contains[] = { +static uint32_t g_q5_invalidates[] = { fpu_d10, fpu_d11, fpu_s20, fpu_s21, fpu_s22, fpu_s23, LLDB_INVALID_REGNUM}; -static uint32_t g_q6_contains[] = { +static uint32_t g_q6_invalidates[] = { fpu_d12, fpu_d13, fpu_s24, fpu_s25, fpu_s26, fpu_s27, LLDB_INVALID_REGNUM}; -static uint32_t g_q7_contains[] = { +static uint32_t g_q7_invalidates[] = { fpu_d14, fpu_d15, fpu_s28, fpu_s29, fpu_s30, fpu_s31, LLDB_INVALID_REGNUM}; -static uint32_t g_q8_contains[] = {fpu_d16, fpu_d17, LLDB_INVALID_REGNUM}; -static uint32_t g_q9_contains[] = {fpu_d18, fpu_d19, LLDB_INVALID_REGNUM}; -static uint32_t g_q10_contains[] = {fpu_d20, fpu_d21, LLDB_INVALID_REGNUM}; -static uint32_t g_q11_contains[] = {fpu_d22, fpu_d23, LLDB_INVALID_REGNUM}; -static uint32_t g_q12_contains[] = {fpu_d24, fpu_d25, LLDB_INVALID_REGNUM}; -static uint32_t g_q13_contains[] = {fpu_d26, fpu_d27, LLDB_INVALID_REGNUM}; -static uint32_t g_q14_contains[] = {fpu_d28, fpu_d29, LLDB_INVALID_REGNUM}; -static uint32_t g_q15_contains[] = {fpu_d30, fpu_d31, LLDB_INVALID_REGNUM}; +static uint32_t g_q8_invalidates[] = {fpu_d16, fpu_d17, LLDB_INVALID_REGNUM}; +static uint32_t g_q9_invalidates[] = {fpu_d18, fpu_d19, LLDB_INVALID_REGNUM}; +static uint32_t g_q10_invalidates[] = {fpu_d20, fpu_d21, LLDB_INVALID_REGNUM}; +static uint32_t g_q11_invalidates[] = {fpu_d22, fpu_d23, LLDB_INVALID_REGNUM}; +static uint32_t g_q12_invalidates[] = {fpu_d24, fpu_d25, LLDB_INVALID_REGNUM}; +static uint32_t g_q13_invalidates[] = {fpu_d26, fpu_d27, LLDB_INVALID_REGNUM}; +static uint32_t g_q14_invalidates[] = {fpu_d28, fpu_d29, LLDB_INVALID_REGNUM}; +static uint32_t g_q15_invalidates[] = {fpu_d30, fpu_d31, LLDB_INVALID_REGNUM}; + +static uint32_t g_q0_contained[] = {fpu_q0, LLDB_INVALID_REGNUM}; +static uint32_t g_q1_contained[] = {fpu_q1, LLDB_INVALID_REGNUM}; +static uint32_t g_q2_contained[] = {fpu_q2, LLDB_INVALID_REGNUM}; +static uint32_t g_q3_contained[] = {fpu_q3, LLDB_INVALID_REGNUM}; +static uint32_t g_q4_contained[] = {fpu_q4, LLDB_INVALID_REGNUM}; +static uint32_t g_q5_contained[] = {fpu_q5, LLDB_INVALID_REGNUM}; +static uint32_t g_q6_contained[] = {fpu_q6, LLDB_INVALID_REGNUM}; +static uint32_t g_q7_contained[] = {fpu_q7, LLDB_INVALID_REGNUM}; +static uint32_t g_q8_contained[] = {fpu_q8, LLDB_INVALID_REGNUM}; +static uint32_t g_q9_contained[] = {fpu_q9, LLDB_INVALID_REGNUM}; +static uint32_t g_q10_contained[] = {fpu_q10, LLDB_INVALID_REGNUM}; +static uint32_t g_q11_contained[] = {fpu_q11, LLDB_INVALID_REGNUM}; +static uint32_t g_q12_contained[] = {fpu_q12, LLDB_INVALID_REGNUM}; +static uint32_t g_q13_contained[] = {fpu_q13, LLDB_INVALID_REGNUM}; +static uint32_t g_q14_contained[] = {fpu_q14, LLDB_INVALID_REGNUM}; +static uint32_t g_q15_contained[] = {fpu_q15, LLDB_INVALID_REGNUM}; + +#define FPU_REG(name, size, offset, qreg) \ + { \ + #name, nullptr, size, FPU_OFFSET(offset), eEncodingIEEE754, eFormatFloat, \ + {LLDB_INVALID_REGNUM, dwarf_##name, LLDB_INVALID_REGNUM, \ + LLDB_INVALID_REGNUM, fpu_##name }, \ + g_##qreg##_contained, g_##name##_invalidates, \ + } + +#define FPU_QREG(name, offset) \ + { \ + #name, nullptr, 16, FPU_OFFSET(offset), eEncodingVector, \ + eFormatVectorOfUInt8, \ + {LLDB_INVALID_REGNUM, dwarf_##name, LLDB_INVALID_REGNUM, \ + LLDB_INVALID_REGNUM, fpu_##name }, \ + nullptr, g_##name##_invalidates, \ + } static RegisterInfo g_register_infos_arm[] = { // NAME ALT SZ OFFSET ENCODING FORMAT @@ -337,1216 +370,343 @@ static RegisterInfo g_register_infos_arm[] = { // ==================== =================== =================== // ========================== =================== ============= // ============== ================= - {"r0", - nullptr, - 4, - GPR_OFFSET(0), - eEncodingUint, - eFormatHex, - {ehframe_r0, dwarf_r0, LLDB_REGNUM_GENERIC_ARG1, LLDB_INVALID_REGNUM, - gpr_r0}, - nullptr, - nullptr, - nullptr, - 0}, - {"r1", - nullptr, - 4, - GPR_OFFSET(1), - eEncodingUint, - eFormatHex, - {ehframe_r1, dwarf_r1, LLDB_REGNUM_GENERIC_ARG2, LLDB_INVALID_REGNUM, - gpr_r1}, - nullptr, - nullptr, - nullptr, - 0}, - {"r2", - nullptr, - 4, - GPR_OFFSET(2), - eEncodingUint, - eFormatHex, - {ehframe_r2, dwarf_r2, LLDB_REGNUM_GENERIC_ARG3, LLDB_INVALID_REGNUM, - gpr_r2}, - nullptr, - nullptr, - nullptr, - 0}, - {"r3", - nullptr, - 4, - GPR_OFFSET(3), - eEncodingUint, - eFormatHex, - {ehframe_r3, dwarf_r3, LLDB_REGNUM_GENERIC_ARG4, LLDB_INVALID_REGNUM, - gpr_r3}, - nullptr, - nullptr, - nullptr, - 0}, - {"r4", - nullptr, - 4, - GPR_OFFSET(4), - eEncodingUint, - eFormatHex, - {ehframe_r4, dwarf_r4, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_r4}, - nullptr, - nullptr, - nullptr, - 0}, - {"r5", - nullptr, - 4, - GPR_OFFSET(5), - eEncodingUint, - eFormatHex, - {ehframe_r5, dwarf_r5, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_r5}, - nullptr, - nullptr, - nullptr, - 0}, - {"r6", - nullptr, - 4, - GPR_OFFSET(6), - eEncodingUint, - eFormatHex, - {ehframe_r6, dwarf_r6, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_r6}, - nullptr, - nullptr, - nullptr, - 0}, - {"r7", - nullptr, - 4, - GPR_OFFSET(7), - eEncodingUint, - eFormatHex, - {ehframe_r7, dwarf_r7, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_r7}, - nullptr, - nullptr, - nullptr, - 0}, - {"r8", - nullptr, - 4, - GPR_OFFSET(8), - eEncodingUint, - eFormatHex, - {ehframe_r8, dwarf_r8, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_r8}, - nullptr, - nullptr, - nullptr, - 0}, - {"r9", - nullptr, - 4, - GPR_OFFSET(9), - eEncodingUint, - eFormatHex, - {ehframe_r9, dwarf_r9, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_r9}, - nullptr, - nullptr, - nullptr, - 0}, - {"r10", - nullptr, - 4, - GPR_OFFSET(10), - eEncodingUint, - eFormatHex, - {ehframe_r10, dwarf_r10, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, - gpr_r10}, - nullptr, - nullptr, - nullptr, - 0}, - {"r11", - nullptr, - 4, - GPR_OFFSET(11), - eEncodingUint, - eFormatHex, - {ehframe_r11, dwarf_r11, LLDB_REGNUM_GENERIC_FP, LLDB_INVALID_REGNUM, - gpr_r11}, - nullptr, - nullptr, - nullptr, - 0}, - {"r12", - nullptr, - 4, - GPR_OFFSET(12), - eEncodingUint, - eFormatHex, - {ehframe_r12, dwarf_r12, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, - gpr_r12}, - nullptr, - nullptr, - nullptr, - 0}, - {"sp", - "r13", - 4, - GPR_OFFSET(13), - eEncodingUint, - eFormatHex, - {ehframe_sp, dwarf_sp, LLDB_REGNUM_GENERIC_SP, LLDB_INVALID_REGNUM, - gpr_sp}, - nullptr, - nullptr, - nullptr, - 0}, - {"lr", - "r14", - 4, - GPR_OFFSET(14), - eEncodingUint, - eFormatHex, - {ehframe_lr, dwarf_lr, LLDB_REGNUM_GENERIC_RA, LLDB_INVALID_REGNUM, - gpr_lr}, - nullptr, - nullptr, - nullptr, - 0}, - {"pc", - "r15", - 4, - GPR_OFFSET(15), - eEncodingUint, - eFormatHex, - {ehframe_pc, dwarf_pc, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_REGNUM, - gpr_pc}, - nullptr, - nullptr, - nullptr, - 0}, - {"cpsr", - "psr", - 4, - GPR_OFFSET(16), - eEncodingUint, - eFormatHex, - {ehframe_cpsr, dwarf_cpsr, LLDB_REGNUM_GENERIC_FLAGS, LLDB_INVALID_REGNUM, - gpr_cpsr}, - nullptr, - nullptr, - nullptr, - 0}, - - {"s0", - nullptr, - 4, - FPU_OFFSET(0), - eEncodingIEEE754, - eFormatFloat, - {LLDB_INVALID_REGNUM, dwarf_s0, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, - fpu_s0}, - nullptr, - g_s0_invalidates, - nullptr, - 0}, - {"s1", - nullptr, - 4, - FPU_OFFSET(1), - eEncodingIEEE754, - eFormatFloat, - {LLDB_INVALID_REGNUM, dwarf_s1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, - fpu_s1}, - nullptr, - g_s1_invalidates, - nullptr, - 0}, - {"s2", - nullptr, - 4, - FPU_OFFSET(2), - eEncodingIEEE754, - eFormatFloat, - {LLDB_INVALID_REGNUM, dwarf_s2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, - fpu_s2}, - nullptr, - g_s2_invalidates, - nullptr, - 0}, - {"s3", - nullptr, - 4, - FPU_OFFSET(3), - eEncodingIEEE754, - eFormatFloat, - {LLDB_INVALID_REGNUM, dwarf_s3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, - fpu_s3}, - nullptr, - g_s3_invalidates, - nullptr, - 0}, - {"s4", - nullptr, - 4, - FPU_OFFSET(4), - eEncodingIEEE754, - eFormatFloat, - {LLDB_INVALID_REGNUM, dwarf_s4, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, - fpu_s4}, - nullptr, - g_s4_invalidates, - nullptr, - 0}, - {"s5", - nullptr, - 4, - FPU_OFFSET(5), - eEncodingIEEE754, - eFormatFloat, - {LLDB_INVALID_REGNUM, dwarf_s5, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, - fpu_s5}, - nullptr, - g_s5_invalidates, - nullptr, - 0}, - {"s6", - nullptr, - 4, - FPU_OFFSET(6), - eEncodingIEEE754, - eFormatFloat, - {LLDB_INVALID_REGNUM, dwarf_s6, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, - fpu_s6}, - nullptr, - g_s6_invalidates, - nullptr, - 0}, - {"s7", - nullptr, - 4, - FPU_OFFSET(7), - eEncodingIEEE754, - eFormatFloat, - {LLDB_INVALID_REGNUM, dwarf_s7, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, - fpu_s7}, - nullptr, - g_s7_invalidates, - nullptr, - 0}, - {"s8", - nullptr, - 4, - FPU_OFFSET(8), - eEncodingIEEE754, - eFormatFloat, - {LLDB_INVALID_REGNUM, dwarf_s8, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, - fpu_s8}, - nullptr, - g_s8_invalidates, - nullptr, - 0}, - {"s9", - nullptr, - 4, - FPU_OFFSET(9), - eEncodingIEEE754, - eFormatFloat, - {LLDB_INVALID_REGNUM, dwarf_s9, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, - fpu_s9}, - nullptr, - g_s9_invalidates, - nullptr, - 0}, - {"s10", - nullptr, - 4, - FPU_OFFSET(10), - eEncodingIEEE754, - eFormatFloat, - {LLDB_INVALID_REGNUM, dwarf_s10, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, - fpu_s10}, - nullptr, - g_s10_invalidates, - nullptr, - 0}, - {"s11", - nullptr, - 4, - FPU_OFFSET(11), - eEncodingIEEE754, - eFormatFloat, - {LLDB_INVALID_REGNUM, dwarf_s11, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, - fpu_s11}, - nullptr, - g_s11_invalidates, - nullptr, - 0}, - {"s12", - nullptr, - 4, - FPU_OFFSET(12), - eEncodingIEEE754, - eFormatFloat, - {LLDB_INVALID_REGNUM, dwarf_s12, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, - fpu_s12}, - nullptr, - g_s12_invalidates, - nullptr, - 0}, - {"s13", - nullptr, - 4, - FPU_OFFSET(13), - eEncodingIEEE754, - eFormatFloat, - {LLDB_INVALID_REGNUM, dwarf_s13, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, - fpu_s13}, - nullptr, - g_s13_invalidates, - nullptr, - 0}, - {"s14", - nullptr, - 4, - FPU_OFFSET(14), - eEncodingIEEE754, - eFormatFloat, - {LLDB_INVALID_REGNUM, dwarf_s14, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, - fpu_s14}, - nullptr, - g_s14_invalidates, - nullptr, - 0}, - {"s15", - nullptr, - 4, - FPU_OFFSET(15), - eEncodingIEEE754, - eFormatFloat, - {LLDB_INVALID_REGNUM, dwarf_s15, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, - fpu_s15}, - nullptr, - g_s15_invalidates, - nullptr, - 0}, - {"s16", - nullptr, - 4, - FPU_OFFSET(16), - eEncodingIEEE754, - eFormatFloat, - {LLDB_INVALID_REGNUM, dwarf_s16, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, - fpu_s16}, - nullptr, - g_s16_invalidates, - nullptr, - 0}, - {"s17", - nullptr, - 4, - FPU_OFFSET(17), - eEncodingIEEE754, - eFormatFloat, - {LLDB_INVALID_REGNUM, dwarf_s17, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, - fpu_s17}, - nullptr, - g_s17_invalidates, - nullptr, - 0}, - {"s18", - nullptr, - 4, - FPU_OFFSET(18), - eEncodingIEEE754, - eFormatFloat, - {LLDB_INVALID_REGNUM, dwarf_s18, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, - fpu_s18}, - nullptr, - g_s18_invalidates, - nullptr, - 0}, - {"s19", - nullptr, - 4, - FPU_OFFSET(19), - eEncodingIEEE754, - eFormatFloat, - {LLDB_INVALID_REGNUM, dwarf_s19, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, - fpu_s19}, - nullptr, - g_s19_invalidates, - nullptr, - 0}, - {"s20", - nullptr, - 4, - FPU_OFFSET(20), - eEncodingIEEE754, - eFormatFloat, - {LLDB_INVALID_REGNUM, dwarf_s20, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, - fpu_s20}, - nullptr, - g_s20_invalidates, - nullptr, - 0}, - {"s21", - nullptr, - 4, - FPU_OFFSET(21), - eEncodingIEEE754, - eFormatFloat, - {LLDB_INVALID_REGNUM, dwarf_s21, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, - fpu_s21}, - nullptr, - g_s21_invalidates, - nullptr, - 0}, - {"s22", - nullptr, - 4, - FPU_OFFSET(22), - eEncodingIEEE754, - eFormatFloat, - {LLDB_INVALID_REGNUM, dwarf_s22, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, - fpu_s22}, - nullptr, - g_s22_invalidates, - nullptr, - 0}, - {"s23", - nullptr, - 4, - FPU_OFFSET(23), - eEncodingIEEE754, - eFormatFloat, - {LLDB_INVALID_REGNUM, dwarf_s23, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, - fpu_s23}, - nullptr, - g_s23_invalidates, - nullptr, - 0}, - {"s24", - nullptr, - 4, - FPU_OFFSET(24), - eEncodingIEEE754, - eFormatFloat, - {LLDB_INVALID_REGNUM, dwarf_s24, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, - fpu_s24}, - nullptr, - g_s24_invalidates, - nullptr, - 0}, - {"s25", - nullptr, - 4, - FPU_OFFSET(25), - eEncodingIEEE754, - eFormatFloat, - {LLDB_INVALID_REGNUM, dwarf_s25, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, - fpu_s25}, - nullptr, - g_s25_invalidates, - nullptr, - 0}, - {"s26", - nullptr, - 4, - FPU_OFFSET(26), - eEncodingIEEE754, - eFormatFloat, - {LLDB_INVALID_REGNUM, dwarf_s26, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, - fpu_s26}, - nullptr, - g_s26_invalidates, - nullptr, - 0}, - {"s27", - nullptr, - 4, - FPU_OFFSET(27), - eEncodingIEEE754, - eFormatFloat, - {LLDB_INVALID_REGNUM, dwarf_s27, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, - fpu_s27}, - nullptr, - g_s27_invalidates, - nullptr, - 0}, - {"s28", - nullptr, - 4, - FPU_OFFSET(28), - eEncodingIEEE754, - eFormatFloat, - {LLDB_INVALID_REGNUM, dwarf_s28, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, - fpu_s28}, - nullptr, - g_s28_invalidates, - nullptr, - 0}, - {"s29", - nullptr, - 4, - FPU_OFFSET(29), - eEncodingIEEE754, - eFormatFloat, - {LLDB_INVALID_REGNUM, dwarf_s29, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, - fpu_s29}, - nullptr, - g_s29_invalidates, - nullptr, - 0}, - {"s30", - nullptr, - 4, - FPU_OFFSET(30), - eEncodingIEEE754, - eFormatFloat, - {LLDB_INVALID_REGNUM, dwarf_s30, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, - fpu_s30}, - nullptr, - g_s30_invalidates, - nullptr, - 0}, - {"s31", - nullptr, - 4, - FPU_OFFSET(31), - eEncodingIEEE754, - eFormatFloat, - {LLDB_INVALID_REGNUM, dwarf_s31, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, - fpu_s31}, - nullptr, - g_s31_invalidates, - nullptr, - 0}, - {"fpscr", - nullptr, - 4, - FPSCR_OFFSET, - eEncodingUint, - eFormatHex, - {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, - LLDB_INVALID_REGNUM, fpu_fpscr}, - nullptr, - nullptr, - nullptr, - 0}, - - {"d0", - nullptr, - 8, - FPU_OFFSET(0), - eEncodingIEEE754, - eFormatFloat, - {LLDB_INVALID_REGNUM, dwarf_d0, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, - fpu_d0}, - g_d0_contains, - g_d0_invalidates, - nullptr, - 0}, - {"d1", - nullptr, - 8, - FPU_OFFSET(2), - eEncodingIEEE754, - eFormatFloat, - {LLDB_INVALID_REGNUM, dwarf_d1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, - fpu_d1}, - g_d1_contains, - g_d1_invalidates, - nullptr, - 0}, - {"d2", - nullptr, - 8, - FPU_OFFSET(4), - eEncodingIEEE754, - eFormatFloat, - {LLDB_INVALID_REGNUM, dwarf_d2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, - fpu_d2}, - g_d2_contains, - g_d2_invalidates, - nullptr, - 0}, - {"d3", - nullptr, - 8, - FPU_OFFSET(6), - eEncodingIEEE754, - eFormatFloat, - {LLDB_INVALID_REGNUM, dwarf_d3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, - fpu_d3}, - g_d3_contains, - g_d3_invalidates, - nullptr, - 0}, - {"d4", - nullptr, - 8, - FPU_OFFSET(8), - eEncodingIEEE754, - eFormatFloat, - {LLDB_INVALID_REGNUM, dwarf_d4, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, - fpu_d4}, - g_d4_contains, - g_d4_invalidates, - nullptr, - 0}, - {"d5", - nullptr, - 8, - FPU_OFFSET(10), - eEncodingIEEE754, - eFormatFloat, - {LLDB_INVALID_REGNUM, dwarf_d5, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, - fpu_d5}, - g_d5_contains, - g_d5_invalidates, - nullptr, - 0}, - {"d6", - nullptr, - 8, - FPU_OFFSET(12), - eEncodingIEEE754, - eFormatFloat, - {LLDB_INVALID_REGNUM, dwarf_d6, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, - fpu_d6}, - g_d6_contains, - g_d6_invalidates, - nullptr, - 0}, - {"d7", - nullptr, - 8, - FPU_OFFSET(14), - eEncodingIEEE754, - eFormatFloat, - {LLDB_INVALID_REGNUM, dwarf_d7, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, - fpu_d7}, - g_d7_contains, - g_d7_invalidates, - nullptr, - 0}, - {"d8", - nullptr, - 8, - FPU_OFFSET(16), - eEncodingIEEE754, - eFormatFloat, - {LLDB_INVALID_REGNUM, dwarf_d8, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, - fpu_d8}, - g_d8_contains, - g_d8_invalidates, - nullptr, - 0}, - {"d9", - nullptr, - 8, - FPU_OFFSET(18), - eEncodingIEEE754, - eFormatFloat, - {LLDB_INVALID_REGNUM, dwarf_d9, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, - fpu_d9}, - g_d9_contains, - g_d9_invalidates, - nullptr, - 0}, - {"d10", - nullptr, - 8, - FPU_OFFSET(20), - eEncodingIEEE754, - eFormatFloat, - {LLDB_INVALID_REGNUM, dwarf_d10, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, - fpu_d10}, - g_d10_contains, - g_d10_invalidates, - nullptr, - 0}, - {"d11", - nullptr, - 8, - FPU_OFFSET(22), - eEncodingIEEE754, - eFormatFloat, - {LLDB_INVALID_REGNUM, dwarf_d11, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, - fpu_d11}, - g_d11_contains, - g_d11_invalidates, - nullptr, - 0}, - {"d12", - nullptr, - 8, - FPU_OFFSET(24), - eEncodingIEEE754, - eFormatFloat, - {LLDB_INVALID_REGNUM, dwarf_d12, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, - fpu_d12}, - g_d12_contains, - g_d12_invalidates, - nullptr, - 0}, - {"d13", - nullptr, - 8, - FPU_OFFSET(26), - eEncodingIEEE754, - eFormatFloat, - {LLDB_INVALID_REGNUM, dwarf_d13, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, - fpu_d13}, - g_d13_contains, - g_d13_invalidates, - nullptr, - 0}, - {"d14", - nullptr, - 8, - FPU_OFFSET(28), - eEncodingIEEE754, - eFormatFloat, - {LLDB_INVALID_REGNUM, dwarf_d14, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, - fpu_d14}, - g_d14_contains, - g_d14_invalidates, - nullptr, - 0}, - {"d15", - nullptr, - 8, - FPU_OFFSET(30), - eEncodingIEEE754, - eFormatFloat, - {LLDB_INVALID_REGNUM, dwarf_d15, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, - fpu_d15}, - g_d15_contains, - g_d15_invalidates, - nullptr, - 0}, - {"d16", - nullptr, - 8, - FPU_OFFSET(32), - eEncodingIEEE754, - eFormatFloat, - {LLDB_INVALID_REGNUM, dwarf_d16, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, - fpu_d16}, - nullptr, - g_d16_invalidates, - nullptr, - 0}, - {"d17", - nullptr, - 8, - FPU_OFFSET(34), - eEncodingIEEE754, - eFormatFloat, - {LLDB_INVALID_REGNUM, dwarf_d17, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, - fpu_d17}, - nullptr, - g_d17_invalidates, - nullptr, - 0}, - {"d18", - nullptr, - 8, - FPU_OFFSET(36), - eEncodingIEEE754, - eFormatFloat, - {LLDB_INVALID_REGNUM, dwarf_d18, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, - fpu_d18}, - nullptr, - g_d18_invalidates, - nullptr, - 0}, - {"d19", - nullptr, - 8, - FPU_OFFSET(38), - eEncodingIEEE754, - eFormatFloat, - {LLDB_INVALID_REGNUM, dwarf_d19, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, - fpu_d19}, - nullptr, - g_d19_invalidates, - nullptr, - 0}, - {"d20", - nullptr, - 8, - FPU_OFFSET(40), - eEncodingIEEE754, - eFormatFloat, - {LLDB_INVALID_REGNUM, dwarf_d20, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, - fpu_d20}, - nullptr, - g_d20_invalidates, - nullptr, - 0}, - {"d21", - nullptr, - 8, - FPU_OFFSET(42), - eEncodingIEEE754, - eFormatFloat, - {LLDB_INVALID_REGNUM, dwarf_d21, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, - fpu_d21}, - nullptr, - g_d21_invalidates, - nullptr, - 0}, - {"d22", - nullptr, - 8, - FPU_OFFSET(44), - eEncodingIEEE754, - eFormatFloat, - {LLDB_INVALID_REGNUM, dwarf_d22, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, - fpu_d22}, - nullptr, - g_d22_invalidates, - nullptr, - 0}, - {"d23", - nullptr, - 8, - FPU_OFFSET(46), - eEncodingIEEE754, - eFormatFloat, - {LLDB_INVALID_REGNUM, dwarf_d23, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, - fpu_d23}, - nullptr, - g_d23_invalidates, - nullptr, - 0}, - {"d24", - nullptr, - 8, - FPU_OFFSET(48), - eEncodingIEEE754, - eFormatFloat, - {LLDB_INVALID_REGNUM, dwarf_d24, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, - fpu_d24}, - nullptr, - g_d24_invalidates, - nullptr, - 0}, - {"d25", - nullptr, - 8, - FPU_OFFSET(50), - eEncodingIEEE754, - eFormatFloat, - {LLDB_INVALID_REGNUM, dwarf_d25, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, - fpu_d25}, - nullptr, - g_d25_invalidates, - nullptr, - 0}, - {"d26", - nullptr, - 8, - FPU_OFFSET(52), - eEncodingIEEE754, - eFormatFloat, - {LLDB_INVALID_REGNUM, dwarf_d26, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, - fpu_d26}, - nullptr, - g_d26_invalidates, - nullptr, - 0}, - {"d27", - nullptr, - 8, - FPU_OFFSET(54), - eEncodingIEEE754, - eFormatFloat, - {LLDB_INVALID_REGNUM, dwarf_d27, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, - fpu_d27}, - nullptr, - g_d27_invalidates, - nullptr, - 0}, - {"d28", - nullptr, - 8, - FPU_OFFSET(56), - eEncodingIEEE754, - eFormatFloat, - {LLDB_INVALID_REGNUM, dwarf_d28, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, - fpu_d28}, - nullptr, - g_d28_invalidates, - nullptr, - 0}, - {"d29", - nullptr, - 8, - FPU_OFFSET(58), - eEncodingIEEE754, - eFormatFloat, - {LLDB_INVALID_REGNUM, dwarf_d29, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, - fpu_d29}, - nullptr, - g_d29_invalidates, - nullptr, - 0}, - {"d30", - nullptr, - 8, - FPU_OFFSET(60), - eEncodingIEEE754, - eFormatFloat, - {LLDB_INVALID_REGNUM, dwarf_d30, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, - fpu_d30}, - nullptr, - g_d30_invalidates, - nullptr, - 0}, - {"d31", - nullptr, - 8, - FPU_OFFSET(62), - eEncodingIEEE754, - eFormatFloat, - {LLDB_INVALID_REGNUM, dwarf_d31, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, - fpu_d31}, - nullptr, - g_d31_invalidates, - nullptr, - 0}, - - {"q0", - nullptr, - 16, - FPU_OFFSET(0), - eEncodingVector, - eFormatVectorOfUInt8, - {LLDB_INVALID_REGNUM, dwarf_q0, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, - fpu_q0}, - g_q0_contains, - nullptr, - nullptr, - 0}, - {"q1", - nullptr, - 16, - FPU_OFFSET(4), - eEncodingVector, - eFormatVectorOfUInt8, - {LLDB_INVALID_REGNUM, dwarf_q1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, - fpu_q1}, - g_q1_contains, - nullptr, - nullptr, - 0}, - {"q2", - nullptr, - 16, - FPU_OFFSET(8), - eEncodingVector, - eFormatVectorOfUInt8, - {LLDB_INVALID_REGNUM, dwarf_q2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, - fpu_q2}, - g_q2_contains, - nullptr, - nullptr, - 0}, - {"q3", - nullptr, - 16, - FPU_OFFSET(12), - eEncodingVector, - eFormatVectorOfUInt8, - {LLDB_INVALID_REGNUM, dwarf_q3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, - fpu_q3}, - g_q3_contains, - nullptr, - nullptr, - 0}, - {"q4", - nullptr, - 16, - FPU_OFFSET(16), - eEncodingVector, - eFormatVectorOfUInt8, - {LLDB_INVALID_REGNUM, dwarf_q4, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, - fpu_q4}, - g_q4_contains, - nullptr, - nullptr, - 0}, - {"q5", - nullptr, - 16, - FPU_OFFSET(20), - eEncodingVector, - eFormatVectorOfUInt8, - {LLDB_INVALID_REGNUM, dwarf_q5, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, - fpu_q5}, - g_q5_contains, - nullptr, - nullptr, - 0}, - {"q6", - nullptr, - 16, - FPU_OFFSET(24), - eEncodingVector, - eFormatVectorOfUInt8, - {LLDB_INVALID_REGNUM, dwarf_q6, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, - fpu_q6}, - g_q6_contains, - nullptr, - nullptr, - 0}, - {"q7", - nullptr, - 16, - FPU_OFFSET(28), - eEncodingVector, - eFormatVectorOfUInt8, - {LLDB_INVALID_REGNUM, dwarf_q7, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, - fpu_q7}, - g_q7_contains, - nullptr, - nullptr, - 0}, - {"q8", - nullptr, - 16, - FPU_OFFSET(32), - eEncodingVector, - eFormatVectorOfUInt8, - {LLDB_INVALID_REGNUM, dwarf_q8, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, - fpu_q8}, - g_q8_contains, - nullptr, - nullptr, - 0}, - {"q9", - nullptr, - 16, - FPU_OFFSET(36), - eEncodingVector, - eFormatVectorOfUInt8, - {LLDB_INVALID_REGNUM, dwarf_q9, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, - fpu_q9}, - g_q9_contains, - nullptr, - nullptr, - 0}, - {"q10", - nullptr, - 16, - FPU_OFFSET(40), - eEncodingVector, - eFormatVectorOfUInt8, - {LLDB_INVALID_REGNUM, dwarf_q10, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, - fpu_q10}, - g_q10_contains, - nullptr, - nullptr, - 0}, - {"q11", - nullptr, - 16, - FPU_OFFSET(44), - eEncodingVector, - eFormatVectorOfUInt8, - {LLDB_INVALID_REGNUM, dwarf_q11, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, - fpu_q11}, - g_q11_contains, - nullptr, - nullptr, - 0}, - {"q12", - nullptr, - 16, - FPU_OFFSET(48), - eEncodingVector, - eFormatVectorOfUInt8, - {LLDB_INVALID_REGNUM, dwarf_q12, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, - fpu_q12}, - g_q12_contains, - nullptr, - nullptr, - 0}, - {"q13", - nullptr, - 16, - FPU_OFFSET(52), - eEncodingVector, - eFormatVectorOfUInt8, - {LLDB_INVALID_REGNUM, dwarf_q13, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, - fpu_q13}, - g_q13_contains, - nullptr, - nullptr, - 0}, - {"q14", - nullptr, - 16, - FPU_OFFSET(56), - eEncodingVector, - eFormatVectorOfUInt8, - {LLDB_INVALID_REGNUM, dwarf_q14, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, - fpu_q14}, - g_q14_contains, - nullptr, - nullptr, - 0}, - {"q15", - nullptr, - 16, - FPU_OFFSET(60), - eEncodingVector, - eFormatVectorOfUInt8, - {LLDB_INVALID_REGNUM, dwarf_q15, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, - fpu_q15}, - g_q15_contains, - nullptr, - nullptr, - 0}, - - {"exception", - nullptr, - 4, - EXC_OFFSET(0), - eEncodingUint, - eFormatHex, - {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, - LLDB_INVALID_REGNUM, exc_exception}, - nullptr, - nullptr, - nullptr, - 0}, - {"fsr", - nullptr, - 4, - EXC_OFFSET(1), - eEncodingUint, - eFormatHex, - {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, - LLDB_INVALID_REGNUM, exc_fsr}, - nullptr, - nullptr, - nullptr, - 0}, - {"far", - nullptr, - 4, - EXC_OFFSET(2), - eEncodingUint, - eFormatHex, - {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, - LLDB_INVALID_REGNUM, exc_far}, - nullptr, - nullptr, - nullptr, - 0}, + { + "r0", + nullptr, + 4, + GPR_OFFSET(0), + eEncodingUint, + eFormatHex, + {ehframe_r0, dwarf_r0, LLDB_REGNUM_GENERIC_ARG1, LLDB_INVALID_REGNUM, + gpr_r0}, + nullptr, + nullptr, + }, + { + "r1", + nullptr, + 4, + GPR_OFFSET(1), + eEncodingUint, + eFormatHex, + {ehframe_r1, dwarf_r1, LLDB_REGNUM_GENERIC_ARG2, LLDB_INVALID_REGNUM, + gpr_r1}, + nullptr, + nullptr, + }, + { + "r2", + nullptr, + 4, + GPR_OFFSET(2), + eEncodingUint, + eFormatHex, + {ehframe_r2, dwarf_r2, LLDB_REGNUM_GENERIC_ARG3, LLDB_INVALID_REGNUM, + gpr_r2}, + nullptr, + nullptr, + }, + { + "r3", + nullptr, + 4, + GPR_OFFSET(3), + eEncodingUint, + eFormatHex, + {ehframe_r3, dwarf_r3, LLDB_REGNUM_GENERIC_ARG4, LLDB_INVALID_REGNUM, + gpr_r3}, + nullptr, + nullptr, + }, + { + "r4", + nullptr, + 4, + GPR_OFFSET(4), + eEncodingUint, + eFormatHex, + {ehframe_r4, dwarf_r4, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + gpr_r4}, + nullptr, + nullptr, + }, + { + "r5", + nullptr, + 4, + GPR_OFFSET(5), + eEncodingUint, + eFormatHex, + {ehframe_r5, dwarf_r5, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + gpr_r5}, + nullptr, + nullptr, + }, + { + "r6", + nullptr, + 4, + GPR_OFFSET(6), + eEncodingUint, + eFormatHex, + {ehframe_r6, dwarf_r6, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + gpr_r6}, + nullptr, + nullptr, + }, + { + "r7", + nullptr, + 4, + GPR_OFFSET(7), + eEncodingUint, + eFormatHex, + {ehframe_r7, dwarf_r7, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + gpr_r7}, + nullptr, + nullptr, + }, + { + "r8", + nullptr, + 4, + GPR_OFFSET(8), + eEncodingUint, + eFormatHex, + {ehframe_r8, dwarf_r8, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + gpr_r8}, + nullptr, + nullptr, + }, + { + "r9", + nullptr, + 4, + GPR_OFFSET(9), + eEncodingUint, + eFormatHex, + {ehframe_r9, dwarf_r9, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + gpr_r9}, + nullptr, + nullptr, + }, + { + "r10", + nullptr, + 4, + GPR_OFFSET(10), + eEncodingUint, + eFormatHex, + {ehframe_r10, dwarf_r10, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + gpr_r10}, + nullptr, + nullptr, + }, + { + "r11", + nullptr, + 4, + GPR_OFFSET(11), + eEncodingUint, + eFormatHex, + {ehframe_r11, dwarf_r11, LLDB_REGNUM_GENERIC_FP, LLDB_INVALID_REGNUM, + gpr_r11}, + nullptr, + nullptr, + }, + { + "r12", + nullptr, + 4, + GPR_OFFSET(12), + eEncodingUint, + eFormatHex, + {ehframe_r12, dwarf_r12, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + gpr_r12}, + nullptr, + nullptr, + }, + { + "sp", + "r13", + 4, + GPR_OFFSET(13), + eEncodingUint, + eFormatHex, + {ehframe_sp, dwarf_sp, LLDB_REGNUM_GENERIC_SP, LLDB_INVALID_REGNUM, + gpr_sp}, + nullptr, + nullptr, + }, + { + "lr", + "r14", + 4, + GPR_OFFSET(14), + eEncodingUint, + eFormatHex, + {ehframe_lr, dwarf_lr, LLDB_REGNUM_GENERIC_RA, LLDB_INVALID_REGNUM, + gpr_lr}, + nullptr, + nullptr, + }, + { + "pc", + "r15", + 4, + GPR_OFFSET(15), + eEncodingUint, + eFormatHex, + {ehframe_pc, dwarf_pc, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_REGNUM, + gpr_pc}, + nullptr, + nullptr, + }, + { + "cpsr", + "psr", + 4, + GPR_OFFSET(16), + eEncodingUint, + eFormatHex, + {ehframe_cpsr, dwarf_cpsr, LLDB_REGNUM_GENERIC_FLAGS, + LLDB_INVALID_REGNUM, gpr_cpsr}, + nullptr, + nullptr, + }, + + FPU_REG(s0, 4, 0, q0), + FPU_REG(s1, 4, 1, q0), + FPU_REG(s2, 4, 2, q0), + FPU_REG(s3, 4, 3, q0), + FPU_REG(s4, 4, 4, q1), + FPU_REG(s5, 4, 5, q1), + FPU_REG(s6, 4, 6, q1), + FPU_REG(s7, 4, 7, q1), + FPU_REG(s8, 4, 8, q2), + FPU_REG(s9, 4, 9, q2), + FPU_REG(s10, 4, 10, q2), + FPU_REG(s11, 4, 11, q2), + FPU_REG(s12, 4, 12, q3), + FPU_REG(s13, 4, 13, q3), + FPU_REG(s14, 4, 14, q3), + FPU_REG(s15, 4, 15, q3), + FPU_REG(s16, 4, 16, q4), + FPU_REG(s17, 4, 17, q4), + FPU_REG(s18, 4, 18, q4), + FPU_REG(s19, 4, 19, q4), + FPU_REG(s20, 4, 20, q5), + FPU_REG(s21, 4, 21, q5), + FPU_REG(s22, 4, 22, q5), + FPU_REG(s23, 4, 23, q5), + FPU_REG(s24, 4, 24, q6), + FPU_REG(s25, 4, 25, q6), + FPU_REG(s26, 4, 26, q6), + FPU_REG(s27, 4, 27, q6), + FPU_REG(s28, 4, 28, q7), + FPU_REG(s29, 4, 29, q7), + FPU_REG(s30, 4, 30, q7), + FPU_REG(s31, 4, 31, q7), + + { + "fpscr", + nullptr, + 4, + FPSCR_OFFSET, + eEncodingUint, + eFormatHex, + {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, fpu_fpscr}, + nullptr, + nullptr, + }, + + FPU_REG(d0, 8, 0, q0), + FPU_REG(d1, 8, 2, q0), + FPU_REG(d2, 8, 4, q1), + FPU_REG(d3, 8, 6, q1), + FPU_REG(d4, 8, 8, q2), + FPU_REG(d5, 8, 10, q2), + FPU_REG(d6, 8, 12, q3), + FPU_REG(d7, 8, 14, q3), + FPU_REG(d8, 8, 16, q4), + FPU_REG(d9, 8, 18, q4), + FPU_REG(d10, 8, 20, q5), + FPU_REG(d11, 8, 22, q5), + FPU_REG(d12, 8, 24, q6), + FPU_REG(d13, 8, 26, q6), + FPU_REG(d14, 8, 28, q7), + FPU_REG(d15, 8, 30, q7), + FPU_REG(d16, 8, 32, q8), + FPU_REG(d17, 8, 34, q8), + FPU_REG(d18, 8, 36, q9), + FPU_REG(d19, 8, 38, q9), + FPU_REG(d20, 8, 40, q10), + FPU_REG(d21, 8, 42, q10), + FPU_REG(d22, 8, 44, q11), + FPU_REG(d23, 8, 46, q11), + FPU_REG(d24, 8, 48, q12), + FPU_REG(d25, 8, 50, q12), + FPU_REG(d26, 8, 52, q13), + FPU_REG(d27, 8, 54, q13), + FPU_REG(d28, 8, 56, q14), + FPU_REG(d29, 8, 58, q14), + FPU_REG(d30, 8, 60, q15), + FPU_REG(d31, 8, 62, q15), + + FPU_QREG(q0, 0), + FPU_QREG(q1, 4), + FPU_QREG(q2, 8), + FPU_QREG(q3, 12), + FPU_QREG(q4, 16), + FPU_QREG(q5, 20), + FPU_QREG(q6, 24), + FPU_QREG(q7, 28), + FPU_QREG(q8, 32), + FPU_QREG(q9, 36), + FPU_QREG(q10, 40), + FPU_QREG(q11, 44), + FPU_QREG(q12, 48), + FPU_QREG(q13, 52), + FPU_QREG(q14, 56), + FPU_QREG(q15, 60), + + { + "exception", + nullptr, + 4, + EXC_OFFSET(0), + eEncodingUint, + eFormatHex, + {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, exc_exception}, + nullptr, + nullptr, + }, + { + "fsr", + nullptr, + 4, + EXC_OFFSET(1), + eEncodingUint, + eFormatHex, + {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, exc_fsr}, + nullptr, + nullptr, + }, + { + "far", + nullptr, + 4, + EXC_OFFSET(2), + eEncodingUint, + eFormatHex, + {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, exc_far}, + nullptr, + nullptr, + }, {DEFINE_DBG(bvr, 0)}, {DEFINE_DBG(bvr, 1)}, diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_arm64.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_arm64.h index 47cedc31bcd7..ccfbd6afbefb 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_arm64.h +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_arm64.h @@ -489,7 +489,6 @@ static uint32_t g_d31_invalidates[] = {fpu_v31, fpu_s31, LLDB_INVALID_REGNUM}; { \ #reg, nullptr, 8, GPR_OFFSET(gpr_##reg), lldb::eEncodingUint, \ lldb::eFormatHex, GPR64_KIND(reg, generic_kind), nullptr, nullptr, \ - nullptr, 0 \ } // Defines a 64-bit general purpose register @@ -497,7 +496,6 @@ static uint32_t g_d31_invalidates[] = {fpu_v31, fpu_s31, LLDB_INVALID_REGNUM}; { \ #reg, #alt, 8, GPR_OFFSET(gpr_##reg), lldb::eEncodingUint, \ lldb::eFormatHex, GPR64_KIND(reg, generic_kind), nullptr, nullptr, \ - nullptr, 0 \ } // Defines a 32-bit general purpose pseudo register @@ -506,15 +504,14 @@ static uint32_t g_d31_invalidates[] = {fpu_v31, fpu_s31, LLDB_INVALID_REGNUM}; #wreg, nullptr, 4, \ GPR_OFFSET(gpr_##xreg) + GPR_W_PSEUDO_REG_ENDIAN_OFFSET, \ lldb::eEncodingUint, lldb::eFormatHex, LLDB_KIND(gpr_##wreg), \ - g_contained_##xreg, g_##wreg##_invalidates, nullptr, 0 \ + g_contained_##xreg, g_##wreg##_invalidates, \ } // Defines a vector register with 16-byte size #define DEFINE_VREG(reg) \ { \ #reg, nullptr, 16, FPU_OFFSET(fpu_##reg - fpu_v0), lldb::eEncodingVector, \ - lldb::eFormatVectorOfUInt8, VREG_KIND(reg), nullptr, nullptr, nullptr, \ - 0 \ + lldb::eFormatVectorOfUInt8, VREG_KIND(reg), nullptr, nullptr, \ } // Defines S and D pseudo registers mapping over corresponding vector register @@ -522,7 +519,7 @@ static uint32_t g_d31_invalidates[] = {fpu_v31, fpu_s31, LLDB_INVALID_REGNUM}; { \ #reg, nullptr, size, FPU_OFFSET(fpu_##vreg - fpu_v0) + offset, \ lldb::eEncodingIEEE754, lldb::eFormatFloat, LLDB_KIND(fpu_##reg), \ - g_contained_##vreg, g_##reg##_invalidates, nullptr, 0 \ + g_contained_##vreg, g_##reg##_invalidates, \ } // Defines miscellaneous status and control registers like cpsr, fpsr etc @@ -530,14 +527,13 @@ static uint32_t g_d31_invalidates[] = {fpu_v31, fpu_s31, LLDB_INVALID_REGNUM}; { \ #reg, nullptr, size, TYPE##_OFFSET_NAME(reg), lldb::eEncodingUint, \ lldb::eFormatHex, MISC_##TYPE##_KIND(lldb_kind), nullptr, nullptr, \ - nullptr, 0 \ } // Defines pointer authentication mask registers #define DEFINE_EXTENSION_REG(reg) \ { \ #reg, nullptr, 8, 0, lldb::eEncodingUint, lldb::eFormatHex, \ - KIND_ALL_INVALID, nullptr, nullptr, nullptr, 0 \ + KIND_ALL_INVALID, nullptr, nullptr, \ } static lldb_private::RegisterInfo g_register_infos_arm64_le[] = { diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_arm64_sve.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_arm64_sve.h index 9551db7e8ebf..b2837b8f1e98 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_arm64_sve.h +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_arm64_sve.h @@ -309,7 +309,6 @@ static uint32_t g_contained_z31[] = {sve_z31, LLDB_INVALID_REGNUM}; { \ #vreg, nullptr, 16, 0, lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, \ VREG_KIND(vreg), g_contained_##zreg, g_sve_##vreg##_invalidates, \ - nullptr, 0 \ } // Defines S and D pseudo registers mapping over corresponding vector register @@ -317,21 +316,20 @@ static uint32_t g_contained_z31[] = {sve_z31, LLDB_INVALID_REGNUM}; { \ #reg, nullptr, size, 0, lldb::eEncodingIEEE754, lldb::eFormatFloat, \ LLDB_KIND(fpu_##reg), g_contained_##zreg, g_sve_##reg##_invalidates, \ - nullptr, 0 \ } // Defines a Z vector register with 16-byte default size #define DEFINE_ZREG(reg) \ { \ #reg, nullptr, 16, 0, lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, \ - SVE_REG_KIND(reg), nullptr, nullptr, nullptr, 0 \ + SVE_REG_KIND(reg), nullptr, nullptr, \ } // Defines a P vector register with 2-byte default size #define DEFINE_PREG(reg) \ { \ #reg, nullptr, 2, 0, lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, \ - SVE_REG_KIND(reg), nullptr, nullptr, nullptr, 0 \ + SVE_REG_KIND(reg), nullptr, nullptr, \ } static lldb_private::RegisterInfo g_register_infos_arm64_sve_le[] = { diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_i386.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_i386.h index 15c7cac544a1..4b73008adb16 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_i386.h +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_i386.h @@ -64,7 +64,7 @@ GPR_OFFSET(reg), eEncodingUint, eFormatHex, \ {kind1, kind2, kind3, kind4, \ lldb_##reg##_i386 }, \ - nullptr, nullptr, nullptr, 0 \ + nullptr, nullptr, \ } #define DEFINE_FPR(name, reg, kind1, kind2, kind3, kind4) \ @@ -72,7 +72,7 @@ #name, nullptr, FPR_SIZE(reg), FPR_OFFSET(reg), eEncodingUint, eFormatHex, \ {kind1, kind2, kind3, kind4, \ lldb_##name##_i386 }, \ - nullptr, nullptr, nullptr, 0 \ + nullptr, nullptr, \ } // RegisterKind: EHFrame, DWARF, Generic, Process Plugin, LLDB @@ -84,7 +84,7 @@ stmm[i]), eEncodingVector, eFormatVectorOfUInt8, \ {ehframe_st##i##_i386, dwarf_st##i##_i386, LLDB_INVALID_REGNUM, \ LLDB_INVALID_REGNUM, lldb_st##i##_i386 }, \ - nullptr, nullptr, nullptr, 0 \ + nullptr, nullptr, \ } #define DEFINE_FP_MM(reg, i, streg) \ @@ -94,7 +94,7 @@ {dwarf_mm##i##_i386, dwarf_mm##i##_i386, LLDB_INVALID_REGNUM, \ LLDB_INVALID_REGNUM, lldb_mm##i##_i386 }, \ RegisterContextPOSIX_x86::g_contained_##streg##_32, \ - RegisterContextPOSIX_x86::g_invalidate_##streg##_32, nullptr, 0 \ + RegisterContextPOSIX_x86::g_invalidate_##streg##_32, \ } #define DEFINE_XMM(reg, i) \ @@ -104,7 +104,7 @@ reg[i]), eEncodingVector, eFormatVectorOfUInt8, \ {ehframe_##reg##i##_i386, dwarf_##reg##i##_i386, \ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, lldb_##reg##i##_i386 }, \ - nullptr, nullptr, nullptr, 0 \ + nullptr, nullptr, \ } // I believe the YMM registers use dwarf_xmm_%_i386 register numbers and then @@ -116,7 +116,7 @@ {LLDB_INVALID_REGNUM, dwarf_xmm##i##_i386, \ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \ lldb_##reg##i##_i386 }, \ - nullptr, nullptr, nullptr, 0 \ + nullptr, nullptr, \ } #define DEFINE_BNDR(reg, i) \ @@ -125,7 +125,7 @@ LLVM_EXTENSION BNDR_OFFSET(i), eEncodingVector, eFormatVectorOfUInt64, \ {dwarf_##reg##i##_i386, dwarf_##reg##i##_i386, LLDB_INVALID_REGNUM, \ LLDB_INVALID_REGNUM, lldb_##reg##i##_i386 }, \ - nullptr, nullptr, nullptr, 0 \ + nullptr, nullptr, \ } #define DEFINE_BNDC(name, i) \ @@ -135,7 +135,7 @@ eFormatVectorOfUInt8, \ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \ LLDB_INVALID_REGNUM, lldb_##name##_i386 }, \ - nullptr, nullptr, nullptr, 0 \ + nullptr, nullptr, \ } #define DEFINE_DR(reg, i) \ @@ -145,7 +145,7 @@ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \ lldb_##reg##i##_i386 }, \ - nullptr, nullptr, nullptr, 0 \ + nullptr, nullptr, \ } #define DEFINE_GPR_PSEUDO_16(reg16, reg32) \ @@ -156,7 +156,7 @@ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \ lldb_##reg16##_i386 }, \ RegisterContextPOSIX_x86::g_contained_##reg32, \ - RegisterContextPOSIX_x86::g_invalidate_##reg32, nullptr, 0 \ + RegisterContextPOSIX_x86::g_invalidate_##reg32, \ } #define DEFINE_GPR_PSEUDO_8H(reg8, reg32) \ @@ -167,7 +167,7 @@ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \ lldb_##reg8##_i386 }, \ RegisterContextPOSIX_x86::g_contained_##reg32, \ - RegisterContextPOSIX_x86::g_invalidate_##reg32, nullptr, 0 \ + RegisterContextPOSIX_x86::g_invalidate_##reg32, \ } #define DEFINE_GPR_PSEUDO_8L(reg8, reg32) \ @@ -178,7 +178,7 @@ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \ lldb_##reg8##_i386 }, \ RegisterContextPOSIX_x86::g_contained_##reg32, \ - RegisterContextPOSIX_x86::g_invalidate_##reg32, nullptr, 0 \ + RegisterContextPOSIX_x86::g_invalidate_##reg32, \ } static RegisterInfo g_register_infos_i386[] = { diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_mips64.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_mips64.h index b28b91810e48..60811d65ffc5 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_mips64.h +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_mips64.h @@ -11,12 +11,16 @@ #include "lldb/Core/dwarf.h" #include "llvm/Support/Compiler.h" - #ifdef DECLARE_REGISTER_INFOS_MIPS64_STRUCT // Computes the offset of the given GPR in the user data area. #define GPR_OFFSET(regname) (LLVM_EXTENSION offsetof(GPR_freebsd_mips, regname)) +// Computes the offset of the given FPR in the extended data area. +#define FPR_OFFSET(regname) \ + (sizeof(GPR_freebsd_mips) + \ + LLVM_EXTENSION offsetof(FPR_freebsd_mips, regname)) + // RegisterKind: EHFrame, DWARF, Generic, Process Plugin, LLDB // Note that the size and offset will be updated by platform-specific classes. @@ -26,9 +30,28 @@ GPR_OFFSET(reg), eEncodingUint, eFormatHex, \ {kind1, kind2, kind3, kind4, \ gpr_##reg##_mips64 }, \ - NULL, NULL, NULL, 0 \ + NULL, NULL \ + } + +#define DEFINE_FPR(reg, alt, kind1, kind2, kind3) \ + { \ + #reg, alt, sizeof(((FPR_freebsd_mips *) 0)->reg), \ + FPR_OFFSET(reg), eEncodingIEEE754, eFormatFloat, \ + {kind1, kind2, kind3, LLDB_INVALID_REGNUM, \ + fpr_##reg##_mips64 }, \ + NULL, NULL, \ } +#define DEFINE_FPR_INFO(reg, alt, kind1, kind2, kind3) \ + { \ + #reg, alt, sizeof(((FPR_freebsd_mips *) 0)->reg), \ + FPR_OFFSET(reg), eEncodingUint, eFormatHex, \ + {kind1, kind2, kind3, LLDB_INVALID_REGNUM, \ + fpr_##reg##_mips64 }, \ + NULL, NULL, \ + } + + static RegisterInfo g_register_infos_mips64[] = { // General purpose registers. EH_Frame, DWARF, // Generic, Process Plugin @@ -112,6 +135,75 @@ static RegisterInfo g_register_infos_mips64[] = { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), DEFINE_GPR(dummy, nullptr, dwarf_dummy_mips64, dwarf_dummy_mips64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + + DEFINE_FPR(f0, nullptr, dwarf_f0_mips64, dwarf_f0_mips64, + LLDB_INVALID_REGNUM), + DEFINE_FPR(f1, nullptr, dwarf_f1_mips64, dwarf_f1_mips64, + LLDB_INVALID_REGNUM), + DEFINE_FPR(f2, nullptr, dwarf_f2_mips64, dwarf_f2_mips64, + LLDB_INVALID_REGNUM), + DEFINE_FPR(f3, nullptr, dwarf_f3_mips64, dwarf_f3_mips64, + LLDB_INVALID_REGNUM), + DEFINE_FPR(f4, nullptr, dwarf_f4_mips64, dwarf_f4_mips64, + LLDB_INVALID_REGNUM), + DEFINE_FPR(f5, nullptr, dwarf_f5_mips64, dwarf_f5_mips64, + LLDB_INVALID_REGNUM), + DEFINE_FPR(f6, nullptr, dwarf_f6_mips64, dwarf_f6_mips64, + LLDB_INVALID_REGNUM), + DEFINE_FPR(f7, nullptr, dwarf_f7_mips64, dwarf_f7_mips64, + LLDB_INVALID_REGNUM), + DEFINE_FPR(f8, nullptr, dwarf_f8_mips64, dwarf_f8_mips64, + LLDB_INVALID_REGNUM), + DEFINE_FPR(f9, nullptr, dwarf_f9_mips64, dwarf_f9_mips64, + LLDB_INVALID_REGNUM), + DEFINE_FPR(f10, nullptr, dwarf_f10_mips64, dwarf_f10_mips64, + LLDB_INVALID_REGNUM), + DEFINE_FPR(f11, nullptr, dwarf_f11_mips64, dwarf_f11_mips64, + LLDB_INVALID_REGNUM), + DEFINE_FPR(f12, nullptr, dwarf_f12_mips64, dwarf_f12_mips64, + LLDB_INVALID_REGNUM), + DEFINE_FPR(f13, nullptr, dwarf_f13_mips64, dwarf_f13_mips64, + LLDB_INVALID_REGNUM), + DEFINE_FPR(f14, nullptr, dwarf_f14_mips64, dwarf_f14_mips64, + LLDB_INVALID_REGNUM), + DEFINE_FPR(f15, nullptr, dwarf_f15_mips64, dwarf_f15_mips64, + LLDB_INVALID_REGNUM), + DEFINE_FPR(f16, nullptr, dwarf_f16_mips64, dwarf_f16_mips64, + LLDB_INVALID_REGNUM), + DEFINE_FPR(f17, nullptr, dwarf_f17_mips64, dwarf_f17_mips64, + LLDB_INVALID_REGNUM), + DEFINE_FPR(f18, nullptr, dwarf_f18_mips64, dwarf_f18_mips64, + LLDB_INVALID_REGNUM), + DEFINE_FPR(f19, nullptr, dwarf_f19_mips64, dwarf_f19_mips64, + LLDB_INVALID_REGNUM), + DEFINE_FPR(f20, nullptr, dwarf_f20_mips64, dwarf_f20_mips64, + LLDB_INVALID_REGNUM), + DEFINE_FPR(f21, nullptr, dwarf_f21_mips64, dwarf_f21_mips64, + LLDB_INVALID_REGNUM), + DEFINE_FPR(f22, nullptr, dwarf_f22_mips64, dwarf_f22_mips64, + LLDB_INVALID_REGNUM), + DEFINE_FPR(f23, nullptr, dwarf_f23_mips64, dwarf_f23_mips64, + LLDB_INVALID_REGNUM), + DEFINE_FPR(f24, nullptr, dwarf_f24_mips64, dwarf_f24_mips64, + LLDB_INVALID_REGNUM), + DEFINE_FPR(f25, nullptr, dwarf_f25_mips64, dwarf_f25_mips64, + LLDB_INVALID_REGNUM), + DEFINE_FPR(f26, nullptr, dwarf_f26_mips64, dwarf_f26_mips64, + LLDB_INVALID_REGNUM), + DEFINE_FPR(f27, nullptr, dwarf_f27_mips64, dwarf_f27_mips64, + LLDB_INVALID_REGNUM), + DEFINE_FPR(f28, nullptr, dwarf_f28_mips64, dwarf_f28_mips64, + LLDB_INVALID_REGNUM), + DEFINE_FPR(f29, nullptr, dwarf_f29_mips64, dwarf_f29_mips64, + LLDB_INVALID_REGNUM), + DEFINE_FPR(f30, nullptr, dwarf_f30_mips64, dwarf_f30_mips64, + LLDB_INVALID_REGNUM), + DEFINE_FPR(f31, nullptr, dwarf_f31_mips64, dwarf_f31_mips64, + LLDB_INVALID_REGNUM), + DEFINE_FPR_INFO(fcsr, nullptr, dwarf_fcsr_mips64, dwarf_fcsr_mips64, + LLDB_INVALID_REGNUM), + DEFINE_FPR_INFO(fir, nullptr, dwarf_fir_mips64, dwarf_fir_mips64, + LLDB_INVALID_REGNUM), }; static_assert((sizeof(g_register_infos_mips64) / diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_powerpc.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_powerpc.h index 04b4171b6722..0fd0a526f921 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_powerpc.h +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_powerpc.h @@ -24,7 +24,7 @@ dwarf_##reg##_powerpc, lldb_kind, \ LLDB_INVALID_REGNUM, \ gpr_##reg##_powerpc }, \ - NULL, NULL, NULL, 0 \ + NULL, NULL, \ } #define DEFINE_FPR(reg, lldb_kind) \ { \ @@ -32,7 +32,7 @@ {dwarf_##reg##_powerpc, dwarf_##reg##_powerpc, \ lldb_kind, LLDB_INVALID_REGNUM, \ fpr_##reg##_powerpc }, \ - NULL, NULL, NULL, 0 \ + NULL, NULL, \ } #define DEFINE_VMX(reg, lldb_kind) \ { \ @@ -40,23 +40,23 @@ {dwarf_##reg##_powerpc, dwarf_##reg##_powerpc, \ lldb_kind, LLDB_INVALID_REGNUM, \ vmx_##reg##_powerpc }, \ - NULL, NULL, NULL, 0 \ + NULL, NULL, \ } // General purpose registers. EH_Frame, DWARF, // Generic, Process Plugin #define POWERPC_REGS \ DEFINE_GPR(r0, NULL, LLDB_INVALID_REGNUM) \ - , DEFINE_GPR(r1, "sp", LLDB_REGNUM_GENERIC_SP), \ + , DEFINE_GPR(r1, NULL, LLDB_REGNUM_GENERIC_SP), \ DEFINE_GPR(r2, NULL, LLDB_INVALID_REGNUM), \ - DEFINE_GPR(r3, "arg1", LLDB_REGNUM_GENERIC_ARG1), \ - DEFINE_GPR(r4, "arg2", LLDB_REGNUM_GENERIC_ARG2), \ - DEFINE_GPR(r5, "arg3", LLDB_REGNUM_GENERIC_ARG3), \ - DEFINE_GPR(r6, "arg4", LLDB_REGNUM_GENERIC_ARG4), \ - DEFINE_GPR(r7, "arg5", LLDB_REGNUM_GENERIC_ARG5), \ - DEFINE_GPR(r8, "arg6", LLDB_REGNUM_GENERIC_ARG6), \ - DEFINE_GPR(r9, "arg7", LLDB_REGNUM_GENERIC_ARG7), \ - DEFINE_GPR(r10, "arg8", LLDB_REGNUM_GENERIC_ARG8), \ + DEFINE_GPR(r3, NULL, LLDB_REGNUM_GENERIC_ARG1), \ + DEFINE_GPR(r4, NULL, LLDB_REGNUM_GENERIC_ARG2), \ + DEFINE_GPR(r5, NULL, LLDB_REGNUM_GENERIC_ARG3), \ + DEFINE_GPR(r6, NULL, LLDB_REGNUM_GENERIC_ARG4), \ + DEFINE_GPR(r7, NULL, LLDB_REGNUM_GENERIC_ARG5), \ + DEFINE_GPR(r8, NULL, LLDB_REGNUM_GENERIC_ARG6), \ + DEFINE_GPR(r9, NULL, LLDB_REGNUM_GENERIC_ARG7), \ + DEFINE_GPR(r10, NULL, LLDB_REGNUM_GENERIC_ARG8), \ DEFINE_GPR(r11, NULL, LLDB_INVALID_REGNUM), \ DEFINE_GPR(r12, NULL, LLDB_INVALID_REGNUM), \ DEFINE_GPR(r13, NULL, LLDB_INVALID_REGNUM), \ @@ -78,11 +78,11 @@ DEFINE_GPR(r29, NULL, LLDB_INVALID_REGNUM), \ DEFINE_GPR(r30, NULL, LLDB_INVALID_REGNUM), \ DEFINE_GPR(r31, NULL, LLDB_INVALID_REGNUM), \ - DEFINE_GPR(lr, "lr", LLDB_REGNUM_GENERIC_RA), \ - DEFINE_GPR(cr, "cr", LLDB_REGNUM_GENERIC_FLAGS), \ - DEFINE_GPR(xer, "xer", LLDB_INVALID_REGNUM), \ - DEFINE_GPR(ctr, "ctr", LLDB_INVALID_REGNUM), \ - DEFINE_GPR(pc, "pc", LLDB_REGNUM_GENERIC_PC), \ + DEFINE_GPR(lr, NULL, LLDB_REGNUM_GENERIC_RA), \ + DEFINE_GPR(cr, NULL, LLDB_REGNUM_GENERIC_FLAGS), \ + DEFINE_GPR(xer, NULL, LLDB_INVALID_REGNUM), \ + DEFINE_GPR(ctr, NULL, LLDB_INVALID_REGNUM), \ + DEFINE_GPR(pc, NULL, LLDB_REGNUM_GENERIC_PC), \ DEFINE_FPR(f0, LLDB_INVALID_REGNUM), \ DEFINE_FPR(f1, LLDB_INVALID_REGNUM), \ DEFINE_FPR(f2, LLDB_INVALID_REGNUM), \ @@ -125,8 +125,7 @@ LLDB_INVALID_REGNUM, fpr_fpscr_powerpc}, \ NULL, \ NULL, \ - NULL, \ - 0}, \ + }, \ DEFINE_VMX(v0, LLDB_INVALID_REGNUM), \ DEFINE_VMX(v1, LLDB_INVALID_REGNUM), \ DEFINE_VMX(v2, LLDB_INVALID_REGNUM), \ @@ -169,8 +168,7 @@ LLDB_INVALID_REGNUM, vmx_vrsave_powerpc}, \ NULL, \ NULL, \ - NULL, \ - 0}, \ + }, \ {"vscr", \ NULL, \ 4, \ @@ -181,8 +179,7 @@ LLDB_INVALID_REGNUM, vmx_vscr_powerpc}, \ NULL, \ NULL, \ - NULL, \ - 0}, + }, static RegisterInfo g_register_infos_powerpc64[] = { #define GPR GPR64 diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_ppc64.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_ppc64.h index 059dba45f9bb..19f2e5627703 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_ppc64.h +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_ppc64.h @@ -31,7 +31,7 @@ lldb_kind, \ LLDB_INVALID_REGNUM, \ gpr_##reg##_ppc64 }, \ - NULL, NULL, NULL, 0 \ + NULL, NULL, \ } #define DEFINE_FPR_PPC64(reg, alt, lldb_kind) \ { \ @@ -40,7 +40,7 @@ {ppc64_dwarf::dwarf_##reg##_ppc64, \ ppc64_dwarf::dwarf_##reg##_ppc64, lldb_kind, LLDB_INVALID_REGNUM, \ fpr_##reg##_ppc64 }, \ - NULL, NULL, NULL, 0 \ + NULL, NULL, \ } #define DEFINE_VMX_PPC64(reg, lldb_kind) \ { \ @@ -49,23 +49,23 @@ {ppc64_dwarf::dwarf_##reg##_ppc64, \ ppc64_dwarf::dwarf_##reg##_ppc64, lldb_kind, LLDB_INVALID_REGNUM, \ vmx_##reg##_ppc64 }, \ - NULL, NULL, NULL, 0 \ + NULL, NULL, \ } // General purpose registers. // EH_Frame, Generic, Process Plugin #define PPC64_REGS \ DEFINE_GPR_PPC64(r0, NULL, LLDB_INVALID_REGNUM) \ - , DEFINE_GPR_PPC64(r1, "sp", LLDB_REGNUM_GENERIC_SP), \ + , DEFINE_GPR_PPC64(r1, NULL, LLDB_REGNUM_GENERIC_SP), \ DEFINE_GPR_PPC64(r2, NULL, LLDB_INVALID_REGNUM), \ - DEFINE_GPR_PPC64(r3, "arg1", LLDB_REGNUM_GENERIC_ARG1), \ - DEFINE_GPR_PPC64(r4, "arg2", LLDB_REGNUM_GENERIC_ARG2), \ - DEFINE_GPR_PPC64(r5, "arg3", LLDB_REGNUM_GENERIC_ARG3), \ - DEFINE_GPR_PPC64(r6, "arg4", LLDB_REGNUM_GENERIC_ARG4), \ - DEFINE_GPR_PPC64(r7, "arg5", LLDB_REGNUM_GENERIC_ARG5), \ - DEFINE_GPR_PPC64(r8, "arg6", LLDB_REGNUM_GENERIC_ARG6), \ - DEFINE_GPR_PPC64(r9, "arg7", LLDB_REGNUM_GENERIC_ARG7), \ - DEFINE_GPR_PPC64(r10, "arg8", LLDB_REGNUM_GENERIC_ARG8), \ + DEFINE_GPR_PPC64(r3, NULL, LLDB_REGNUM_GENERIC_ARG1), \ + DEFINE_GPR_PPC64(r4, NULL, LLDB_REGNUM_GENERIC_ARG2), \ + DEFINE_GPR_PPC64(r5, NULL, LLDB_REGNUM_GENERIC_ARG3), \ + DEFINE_GPR_PPC64(r6, NULL, LLDB_REGNUM_GENERIC_ARG4), \ + DEFINE_GPR_PPC64(r7, NULL, LLDB_REGNUM_GENERIC_ARG5), \ + DEFINE_GPR_PPC64(r8, NULL, LLDB_REGNUM_GENERIC_ARG6), \ + DEFINE_GPR_PPC64(r9, NULL, LLDB_REGNUM_GENERIC_ARG7), \ + DEFINE_GPR_PPC64(r10, NULL, LLDB_REGNUM_GENERIC_ARG8), \ DEFINE_GPR_PPC64(r11, NULL, LLDB_INVALID_REGNUM), \ DEFINE_GPR_PPC64(r12, NULL, LLDB_INVALID_REGNUM), \ DEFINE_GPR_PPC64(r13, NULL, LLDB_INVALID_REGNUM), \ @@ -87,12 +87,12 @@ DEFINE_GPR_PPC64(r29, NULL, LLDB_INVALID_REGNUM), \ DEFINE_GPR_PPC64(r30, NULL, LLDB_INVALID_REGNUM), \ DEFINE_GPR_PPC64(r31, NULL, LLDB_INVALID_REGNUM), \ - DEFINE_GPR_PPC64(cr, "cr", LLDB_REGNUM_GENERIC_FLAGS), \ - DEFINE_GPR_PPC64(msr, "msr", LLDB_INVALID_REGNUM), \ - DEFINE_GPR_PPC64(xer, "xer", LLDB_INVALID_REGNUM), \ - DEFINE_GPR_PPC64(lr, "lr", LLDB_REGNUM_GENERIC_RA), \ - DEFINE_GPR_PPC64(ctr, "ctr", LLDB_INVALID_REGNUM), \ - DEFINE_GPR_PPC64(pc, "pc", LLDB_REGNUM_GENERIC_PC), \ + DEFINE_GPR_PPC64(cr, NULL, LLDB_REGNUM_GENERIC_FLAGS), \ + DEFINE_GPR_PPC64(msr, NULL, LLDB_INVALID_REGNUM), \ + DEFINE_GPR_PPC64(xer, NULL, LLDB_INVALID_REGNUM), \ + DEFINE_GPR_PPC64(lr, NULL, LLDB_REGNUM_GENERIC_RA), \ + DEFINE_GPR_PPC64(ctr, NULL, LLDB_INVALID_REGNUM), \ + DEFINE_GPR_PPC64(pc, NULL, LLDB_REGNUM_GENERIC_PC), \ DEFINE_FPR_PPC64(f0, NULL, LLDB_INVALID_REGNUM), \ DEFINE_FPR_PPC64(f1, NULL, LLDB_INVALID_REGNUM), \ DEFINE_FPR_PPC64(f2, NULL, LLDB_INVALID_REGNUM), \ @@ -136,8 +136,7 @@ LLDB_INVALID_REGNUM, fpr_fpscr_ppc64}, \ NULL, \ NULL, \ - NULL, \ - 0}, \ + }, \ DEFINE_VMX_PPC64(vr0, LLDB_INVALID_REGNUM), \ DEFINE_VMX_PPC64(vr1, LLDB_INVALID_REGNUM), \ DEFINE_VMX_PPC64(vr2, LLDB_INVALID_REGNUM), \ @@ -180,8 +179,7 @@ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, vmx_vscr_ppc64}, \ NULL, \ NULL, \ - NULL, \ - 0}, \ + }, \ {"vrsave", \ NULL, \ 4, \ @@ -193,8 +191,7 @@ LLDB_INVALID_REGNUM, vmx_vrsave_ppc64}, \ NULL, \ NULL, \ - NULL, \ - 0}, /* */ + }, /* */ typedef struct _GPR_PPC64 { uint64_t r0; diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_ppc64le.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_ppc64le.h index 9937da2f3050..f8f8651c856c 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_ppc64le.h +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_ppc64le.h @@ -31,7 +31,7 @@ lldb_kind, \ LLDB_INVALID_REGNUM, \ gpr_##reg##_ppc64le }, \ - NULL, NULL, NULL, 0 \ + NULL, NULL, \ } #define DEFINE_FPR(reg, alt, lldb_kind) \ { \ @@ -39,7 +39,7 @@ {ppc64le_dwarf::dwarf_##reg##_ppc64le, \ ppc64le_dwarf::dwarf_##reg##_ppc64le, lldb_kind, LLDB_INVALID_REGNUM, \ fpr_##reg##_ppc64le }, \ - NULL, NULL, NULL, 0 \ + NULL, NULL, \ } #define DEFINE_VMX(reg, lldb_kind) \ { \ @@ -48,7 +48,7 @@ {ppc64le_dwarf::dwarf_##reg##_ppc64le, \ ppc64le_dwarf::dwarf_##reg##_ppc64le, lldb_kind, LLDB_INVALID_REGNUM, \ vmx_##reg##_ppc64le }, \ - NULL, NULL, NULL, 0 \ + NULL, NULL, \ } #define DEFINE_VSX(reg, lldb_kind) \ { \ @@ -57,23 +57,23 @@ {ppc64le_dwarf::dwarf_##reg##_ppc64le, \ ppc64le_dwarf::dwarf_##reg##_ppc64le, lldb_kind, LLDB_INVALID_REGNUM, \ vsx_##reg##_ppc64le }, \ - NULL, NULL, NULL, 0 \ + NULL, NULL, \ } // General purpose registers. // EH_Frame, Generic, Process Plugin #define POWERPC_REGS \ DEFINE_GPR(r0, NULL, LLDB_INVALID_REGNUM) \ - , DEFINE_GPR(r1, "sp", LLDB_REGNUM_GENERIC_SP), \ + , DEFINE_GPR(r1, NULL, LLDB_REGNUM_GENERIC_SP), \ DEFINE_GPR(r2, NULL, LLDB_INVALID_REGNUM), \ - DEFINE_GPR(r3, "arg1", LLDB_REGNUM_GENERIC_ARG1), \ - DEFINE_GPR(r4, "arg2", LLDB_REGNUM_GENERIC_ARG2), \ - DEFINE_GPR(r5, "arg3", LLDB_REGNUM_GENERIC_ARG3), \ - DEFINE_GPR(r6, "arg4", LLDB_REGNUM_GENERIC_ARG4), \ - DEFINE_GPR(r7, "arg5", LLDB_REGNUM_GENERIC_ARG5), \ - DEFINE_GPR(r8, "arg6", LLDB_REGNUM_GENERIC_ARG6), \ - DEFINE_GPR(r9, "arg7", LLDB_REGNUM_GENERIC_ARG7), \ - DEFINE_GPR(r10, "arg8", LLDB_REGNUM_GENERIC_ARG8), \ + DEFINE_GPR(r3, NULL, LLDB_REGNUM_GENERIC_ARG1), \ + DEFINE_GPR(r4, NULL, LLDB_REGNUM_GENERIC_ARG2), \ + DEFINE_GPR(r5, NULL, LLDB_REGNUM_GENERIC_ARG3), \ + DEFINE_GPR(r6, NULL, LLDB_REGNUM_GENERIC_ARG4), \ + DEFINE_GPR(r7, NULL, LLDB_REGNUM_GENERIC_ARG5), \ + DEFINE_GPR(r8, NULL, LLDB_REGNUM_GENERIC_ARG6), \ + DEFINE_GPR(r9, NULL, LLDB_REGNUM_GENERIC_ARG7), \ + DEFINE_GPR(r10, NULL, LLDB_REGNUM_GENERIC_ARG8), \ DEFINE_GPR(r11, NULL, LLDB_INVALID_REGNUM), \ DEFINE_GPR(r12, NULL, LLDB_INVALID_REGNUM), \ DEFINE_GPR(r13, NULL, LLDB_INVALID_REGNUM), \ @@ -95,15 +95,15 @@ DEFINE_GPR(r29, NULL, LLDB_INVALID_REGNUM), \ DEFINE_GPR(r30, NULL, LLDB_INVALID_REGNUM), \ DEFINE_GPR(r31, NULL, LLDB_INVALID_REGNUM), \ - DEFINE_GPR(pc, "pc", LLDB_REGNUM_GENERIC_PC), \ - DEFINE_GPR(msr, "msr", LLDB_INVALID_REGNUM), \ + DEFINE_GPR(pc, NULL, LLDB_REGNUM_GENERIC_PC), \ + DEFINE_GPR(msr, NULL, LLDB_INVALID_REGNUM), \ DEFINE_GPR(origr3, "orig_r3", LLDB_INVALID_REGNUM), \ - DEFINE_GPR(ctr, "ctr", LLDB_INVALID_REGNUM), \ - DEFINE_GPR(lr, "lr", LLDB_REGNUM_GENERIC_RA), \ - DEFINE_GPR(xer, "xer", LLDB_INVALID_REGNUM), \ - DEFINE_GPR(cr, "cr", LLDB_REGNUM_GENERIC_FLAGS), \ - DEFINE_GPR(softe, "softe", LLDB_INVALID_REGNUM), \ - DEFINE_GPR(trap, "trap", LLDB_INVALID_REGNUM), \ + DEFINE_GPR(ctr, NULL, LLDB_INVALID_REGNUM), \ + DEFINE_GPR(lr, NULL, LLDB_REGNUM_GENERIC_RA), \ + DEFINE_GPR(xer, NULL, LLDB_INVALID_REGNUM), \ + DEFINE_GPR(cr, NULL, LLDB_REGNUM_GENERIC_FLAGS), \ + DEFINE_GPR(softe, NULL, LLDB_INVALID_REGNUM), \ + DEFINE_GPR(trap, NULL, LLDB_INVALID_REGNUM), \ DEFINE_FPR(f0, NULL, LLDB_INVALID_REGNUM), \ DEFINE_FPR(f1, NULL, LLDB_INVALID_REGNUM), \ DEFINE_FPR(f2, NULL, LLDB_INVALID_REGNUM), \ @@ -147,8 +147,7 @@ LLDB_INVALID_REGNUM, fpr_fpscr_ppc64le}, \ NULL, \ NULL, \ - NULL, \ - 0}, \ + }, \ DEFINE_VMX(vr0, LLDB_INVALID_REGNUM), \ DEFINE_VMX(vr1, LLDB_INVALID_REGNUM), \ DEFINE_VMX(vr2, LLDB_INVALID_REGNUM), \ @@ -191,8 +190,7 @@ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, vmx_vscr_ppc64le}, \ NULL, \ NULL, \ - NULL, \ - 0}, \ + }, \ {"vrsave", \ NULL, \ 4, \ @@ -204,8 +202,7 @@ LLDB_INVALID_REGNUM, vmx_vrsave_ppc64le}, \ NULL, \ NULL, \ - NULL, \ - 0}, \ + }, \ DEFINE_VSX(vs0, LLDB_INVALID_REGNUM), \ DEFINE_VSX(vs1, LLDB_INVALID_REGNUM), \ DEFINE_VSX(vs2, LLDB_INVALID_REGNUM), \ diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_s390x.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_s390x.h index d1df7c606207..65878b04eed8 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_s390x.h +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_s390x.h @@ -27,7 +27,7 @@ #name, alt, size, offset, eEncodingUint, eFormatHex, \ {dwarf_##name##_s390x, dwarf_##name##_s390x, generic, \ LLDB_INVALID_REGNUM, lldb_##name##_s390x }, \ - NULL, NULL, NULL, 0 \ + NULL, NULL, \ } #define DEFINE_GPR_NODWARF(name, size, offset, alt, generic) \ @@ -35,7 +35,7 @@ #name, alt, size, offset, eEncodingUint, eFormatHex, \ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, generic, \ LLDB_INVALID_REGNUM, lldb_##name##_s390x }, \ - NULL, NULL, NULL, 0 \ + NULL, NULL, \ } #define DEFINE_FPR(name, size, offset) \ @@ -43,7 +43,7 @@ #name, NULL, size, offset, eEncodingUint, eFormatHex, \ {dwarf_##name##_s390x, dwarf_##name##_s390x, LLDB_INVALID_REGNUM, \ LLDB_INVALID_REGNUM, lldb_##name##_s390x }, \ - NULL, NULL, NULL, 0 \ + NULL, NULL, \ } #define DEFINE_FPR_NODWARF(name, size, offset) \ @@ -51,27 +51,27 @@ #name, NULL, size, offset, eEncodingUint, eFormatHex, \ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \ LLDB_INVALID_REGNUM, lldb_##name##_s390x }, \ - NULL, NULL, NULL, 0 \ + NULL, NULL, \ } static RegisterInfo g_register_infos_s390x[] = { // General purpose registers. DEFINE_GPR(r0, 8, GPR_OFFSET(0), nullptr, LLDB_INVALID_REGNUM), DEFINE_GPR(r1, 8, GPR_OFFSET(1), nullptr, LLDB_INVALID_REGNUM), - DEFINE_GPR(r2, 8, GPR_OFFSET(2), "arg1", LLDB_REGNUM_GENERIC_ARG1), - DEFINE_GPR(r3, 8, GPR_OFFSET(3), "arg2", LLDB_REGNUM_GENERIC_ARG2), - DEFINE_GPR(r4, 8, GPR_OFFSET(4), "arg3", LLDB_REGNUM_GENERIC_ARG3), - DEFINE_GPR(r5, 8, GPR_OFFSET(5), "arg4", LLDB_REGNUM_GENERIC_ARG4), - DEFINE_GPR(r6, 8, GPR_OFFSET(6), "arg5", LLDB_REGNUM_GENERIC_ARG5), + DEFINE_GPR(r2, 8, GPR_OFFSET(2), nullptr, LLDB_REGNUM_GENERIC_ARG1), + DEFINE_GPR(r3, 8, GPR_OFFSET(3), nullptr, LLDB_REGNUM_GENERIC_ARG2), + DEFINE_GPR(r4, 8, GPR_OFFSET(4), nullptr, LLDB_REGNUM_GENERIC_ARG3), + DEFINE_GPR(r5, 8, GPR_OFFSET(5), nullptr, LLDB_REGNUM_GENERIC_ARG4), + DEFINE_GPR(r6, 8, GPR_OFFSET(6), nullptr, LLDB_REGNUM_GENERIC_ARG5), DEFINE_GPR(r7, 8, GPR_OFFSET(7), nullptr, LLDB_INVALID_REGNUM), DEFINE_GPR(r8, 8, GPR_OFFSET(8), nullptr, LLDB_INVALID_REGNUM), DEFINE_GPR(r9, 8, GPR_OFFSET(9), nullptr, LLDB_INVALID_REGNUM), DEFINE_GPR(r10, 8, GPR_OFFSET(10), nullptr, LLDB_INVALID_REGNUM), - DEFINE_GPR(r11, 8, GPR_OFFSET(11), "fp", LLDB_REGNUM_GENERIC_FP), + DEFINE_GPR(r11, 8, GPR_OFFSET(11), nullptr, LLDB_REGNUM_GENERIC_FP), DEFINE_GPR(r12, 8, GPR_OFFSET(12), nullptr, LLDB_INVALID_REGNUM), DEFINE_GPR(r13, 8, GPR_OFFSET(13), nullptr, LLDB_INVALID_REGNUM), DEFINE_GPR(r14, 8, GPR_OFFSET(14), nullptr, LLDB_INVALID_REGNUM), - DEFINE_GPR(r15, 8, GPR_OFFSET(15), "sp", LLDB_REGNUM_GENERIC_SP), + DEFINE_GPR(r15, 8, GPR_OFFSET(15), nullptr, LLDB_REGNUM_GENERIC_SP), DEFINE_GPR(acr0, 4, ACR_OFFSET(0), nullptr, LLDB_INVALID_REGNUM), DEFINE_GPR(acr1, 4, ACR_OFFSET(1), nullptr, LLDB_INVALID_REGNUM), DEFINE_GPR(acr2, 4, ACR_OFFSET(2), nullptr, LLDB_INVALID_REGNUM), @@ -88,8 +88,8 @@ static RegisterInfo g_register_infos_s390x[] = { DEFINE_GPR(acr13, 4, ACR_OFFSET(13), nullptr, LLDB_INVALID_REGNUM), DEFINE_GPR(acr14, 4, ACR_OFFSET(14), nullptr, LLDB_INVALID_REGNUM), DEFINE_GPR(acr15, 4, ACR_OFFSET(15), nullptr, LLDB_INVALID_REGNUM), - DEFINE_GPR(pswm, 8, 0, "flags", LLDB_REGNUM_GENERIC_FLAGS), - DEFINE_GPR(pswa, 8, 8, "pc", LLDB_REGNUM_GENERIC_PC), + DEFINE_GPR(pswm, 8, 0, nullptr, LLDB_REGNUM_GENERIC_FLAGS), + DEFINE_GPR(pswa, 8, 8, nullptr, LLDB_REGNUM_GENERIC_PC), // Floating point registers. DEFINE_FPR(f0, 8, FPR_OFFSET(0)), DEFINE_FPR(f1, 8, FPR_OFFSET(1)), diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_x86_64.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_x86_64.h index 41c04b20f391..1de67165fb2f 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_x86_64.h +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_x86_64.h @@ -67,7 +67,7 @@ GPR_OFFSET(reg), eEncodingUint, eFormatHex, \ {kind1, kind2, kind3, kind4, \ lldb_##reg##_x86_64 }, \ - nullptr, nullptr, nullptr, 0 \ + nullptr, nullptr, \ } #define DEFINE_FPR(name, reg, kind1, kind2, kind3, kind4) \ @@ -75,7 +75,7 @@ #name, nullptr, FPR_SIZE(reg), FPR_OFFSET(reg), eEncodingUint, eFormatHex, \ {kind1, kind2, kind3, kind4, \ lldb_##name##_x86_64 }, \ - nullptr, nullptr, nullptr, 0 \ + nullptr, nullptr, \ } #define DEFINE_FP_ST(reg, i) \ @@ -85,7 +85,7 @@ stmm[i]), eEncodingVector, eFormatVectorOfUInt8, \ {dwarf_st##i##_x86_64, dwarf_st##i##_x86_64, LLDB_INVALID_REGNUM, \ LLDB_INVALID_REGNUM, lldb_st##i##_x86_64 }, \ - nullptr, nullptr, nullptr, 0 \ + nullptr, nullptr, \ } #define DEFINE_FP_MM(reg, i, streg) \ @@ -95,7 +95,7 @@ {dwarf_mm##i##_x86_64, dwarf_mm##i##_x86_64, LLDB_INVALID_REGNUM, \ LLDB_INVALID_REGNUM, lldb_mm##i##_x86_64 }, \ RegisterContextPOSIX_x86::g_contained_##streg##_64, \ - RegisterContextPOSIX_x86::g_invalidate_##streg##_64, nullptr, 0 \ + RegisterContextPOSIX_x86::g_invalidate_##streg##_64, \ } #define DEFINE_XMM(reg, i) \ @@ -106,7 +106,7 @@ {dwarf_##reg##i##_x86_64, dwarf_##reg##i##_x86_64, \ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \ lldb_##reg##i##_x86_64 }, \ - nullptr, nullptr, nullptr, 0 \ + nullptr, nullptr, \ } #define DEFINE_YMM(reg, i) \ @@ -117,7 +117,7 @@ dwarf_##reg##i##h_x86_64, \ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \ lldb_##reg##i##_x86_64 }, \ - nullptr, nullptr, nullptr, 0 \ + nullptr, nullptr, \ } #define DEFINE_BNDR(reg, i) \ @@ -128,7 +128,7 @@ dwarf_##reg##i##_x86_64, \ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \ lldb_##reg##i##_x86_64 }, \ - nullptr, nullptr, nullptr, 0 \ + nullptr, nullptr, \ } #define DEFINE_BNDC(name, i) \ @@ -137,7 +137,7 @@ LLVM_EXTENSION BNDC_OFFSET(i), eEncodingVector, eFormatVectorOfUInt8, \ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \ LLDB_INVALID_REGNUM, lldb_##name##_x86_64 }, \ - nullptr, nullptr, nullptr, 0 \ + nullptr, nullptr, \ } #define DEFINE_DR(reg, i) \ @@ -147,7 +147,7 @@ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \ lldb_##reg##i##_x86_64 }, \ - nullptr, nullptr, nullptr, 0 \ + nullptr, nullptr, \ } #define DEFINE_GPR_PSEUDO_32(reg32, reg64) \ @@ -158,7 +158,7 @@ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \ lldb_##reg32##_x86_64 }, \ RegisterContextPOSIX_x86::g_contained_##reg64, \ - RegisterContextPOSIX_x86::g_invalidate_##reg64, nullptr, 0 \ + RegisterContextPOSIX_x86::g_invalidate_##reg64, \ } #define DEFINE_GPR_PSEUDO_16(reg16, reg64) \ @@ -169,7 +169,7 @@ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \ lldb_##reg16##_x86_64 }, \ RegisterContextPOSIX_x86::g_contained_##reg64, \ - RegisterContextPOSIX_x86::g_invalidate_##reg64, nullptr, 0 \ + RegisterContextPOSIX_x86::g_invalidate_##reg64, \ } #define DEFINE_GPR_PSEUDO_8H(reg8, reg64) \ @@ -180,7 +180,7 @@ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \ lldb_##reg8##_x86_64 }, \ RegisterContextPOSIX_x86::g_contained_##reg64, \ - RegisterContextPOSIX_x86::g_invalidate_##reg64, nullptr, 0 \ + RegisterContextPOSIX_x86::g_invalidate_##reg64, \ } #define DEFINE_GPR_PSEUDO_8L(reg8, reg64) \ @@ -191,7 +191,7 @@ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \ lldb_##reg8##_x86_64 }, \ RegisterContextPOSIX_x86::g_contained_##reg64, \ - RegisterContextPOSIX_x86::g_invalidate_##reg64, nullptr, 0 \ + RegisterContextPOSIX_x86::g_invalidate_##reg64, \ } #define DEFINE_FPR_32(name, reg, kind1, kind2, kind3, kind4, reg64) \ @@ -199,7 +199,7 @@ #name, nullptr, FPR_SIZE(reg), FPR_OFFSET(reg), eEncodingUint, eFormatHex, \ {kind1, kind2, kind3, kind4, lldb_##name##_x86_64 }, \ RegisterContextPOSIX_x86::g_contained_##reg64, \ - RegisterContextPOSIX_x86::g_invalidate_##reg64, nullptr, 0 \ + RegisterContextPOSIX_x86::g_invalidate_##reg64, \ } // clang-format off @@ -208,22 +208,22 @@ static RegisterInfo g_register_infos_x86_64[] = { // =========================== ================== ================ ========================= ==================== DEFINE_GPR(rax, nullptr, dwarf_rax_x86_64, dwarf_rax_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), DEFINE_GPR(rbx, nullptr, dwarf_rbx_x86_64, dwarf_rbx_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), - DEFINE_GPR(rcx, "arg4", dwarf_rcx_x86_64, dwarf_rcx_x86_64, LLDB_REGNUM_GENERIC_ARG4, LLDB_INVALID_REGNUM), - DEFINE_GPR(rdx, "arg3", dwarf_rdx_x86_64, dwarf_rdx_x86_64, LLDB_REGNUM_GENERIC_ARG3, LLDB_INVALID_REGNUM), - DEFINE_GPR(rdi, "arg1", dwarf_rdi_x86_64, dwarf_rdi_x86_64, LLDB_REGNUM_GENERIC_ARG1, LLDB_INVALID_REGNUM), - DEFINE_GPR(rsi, "arg2", dwarf_rsi_x86_64, dwarf_rsi_x86_64, LLDB_REGNUM_GENERIC_ARG2, LLDB_INVALID_REGNUM), - DEFINE_GPR(rbp, "fp", dwarf_rbp_x86_64, dwarf_rbp_x86_64, LLDB_REGNUM_GENERIC_FP, LLDB_INVALID_REGNUM), - DEFINE_GPR(rsp, "sp", dwarf_rsp_x86_64, dwarf_rsp_x86_64, LLDB_REGNUM_GENERIC_SP, LLDB_INVALID_REGNUM), - DEFINE_GPR(r8, "arg5", dwarf_r8_x86_64, dwarf_r8_x86_64, LLDB_REGNUM_GENERIC_ARG5, LLDB_INVALID_REGNUM), - DEFINE_GPR(r9, "arg6", dwarf_r9_x86_64, dwarf_r9_x86_64, LLDB_REGNUM_GENERIC_ARG6, LLDB_INVALID_REGNUM), + DEFINE_GPR(rcx, nullptr, dwarf_rcx_x86_64, dwarf_rcx_x86_64, LLDB_REGNUM_GENERIC_ARG4, LLDB_INVALID_REGNUM), + DEFINE_GPR(rdx, nullptr, dwarf_rdx_x86_64, dwarf_rdx_x86_64, LLDB_REGNUM_GENERIC_ARG3, LLDB_INVALID_REGNUM), + DEFINE_GPR(rdi, nullptr, dwarf_rdi_x86_64, dwarf_rdi_x86_64, LLDB_REGNUM_GENERIC_ARG1, LLDB_INVALID_REGNUM), + DEFINE_GPR(rsi, nullptr, dwarf_rsi_x86_64, dwarf_rsi_x86_64, LLDB_REGNUM_GENERIC_ARG2, LLDB_INVALID_REGNUM), + DEFINE_GPR(rbp, nullptr, dwarf_rbp_x86_64, dwarf_rbp_x86_64, LLDB_REGNUM_GENERIC_FP, LLDB_INVALID_REGNUM), + DEFINE_GPR(rsp, nullptr, dwarf_rsp_x86_64, dwarf_rsp_x86_64, LLDB_REGNUM_GENERIC_SP, LLDB_INVALID_REGNUM), + DEFINE_GPR(r8, nullptr, dwarf_r8_x86_64, dwarf_r8_x86_64, LLDB_REGNUM_GENERIC_ARG5, LLDB_INVALID_REGNUM), + DEFINE_GPR(r9, nullptr, dwarf_r9_x86_64, dwarf_r9_x86_64, LLDB_REGNUM_GENERIC_ARG6, LLDB_INVALID_REGNUM), DEFINE_GPR(r10, nullptr, dwarf_r10_x86_64, dwarf_r10_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), DEFINE_GPR(r11, nullptr, dwarf_r11_x86_64, dwarf_r11_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), DEFINE_GPR(r12, nullptr, dwarf_r12_x86_64, dwarf_r12_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), DEFINE_GPR(r13, nullptr, dwarf_r13_x86_64, dwarf_r13_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), DEFINE_GPR(r14, nullptr, dwarf_r14_x86_64, dwarf_r14_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), DEFINE_GPR(r15, nullptr, dwarf_r15_x86_64, dwarf_r15_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), - DEFINE_GPR(rip, "pc", dwarf_rip_x86_64, dwarf_rip_x86_64, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_REGNUM), - DEFINE_GPR(rflags, "flags", dwarf_rflags_x86_64, dwarf_rflags_x86_64, LLDB_REGNUM_GENERIC_FLAGS, LLDB_INVALID_REGNUM), + DEFINE_GPR(rip, nullptr, dwarf_rip_x86_64, dwarf_rip_x86_64, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_REGNUM), + DEFINE_GPR(rflags, nullptr, dwarf_rflags_x86_64, dwarf_rflags_x86_64, LLDB_REGNUM_GENERIC_FLAGS, LLDB_INVALID_REGNUM), DEFINE_GPR(cs, nullptr, dwarf_cs_x86_64, dwarf_cs_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), DEFINE_GPR(fs, nullptr, dwarf_fs_x86_64, dwarf_fs_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), DEFINE_GPR(gs, nullptr, dwarf_gs_x86_64, dwarf_gs_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/StopInfoMachException.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/StopInfoMachException.cpp index 85785a20354d..4df210032153 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/StopInfoMachException.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/StopInfoMachException.cpp @@ -17,6 +17,7 @@ #include "lldb/Breakpoint/Watchpoint.h" #include "lldb/Symbol/Symbol.h" +#include "lldb/Target/ABI.h" #include "lldb/Target/DynamicLoader.h" #include "lldb/Target/ExecutionContext.h" #include "lldb/Target/Process.h" @@ -30,6 +31,182 @@ using namespace lldb; using namespace lldb_private; +/// Information about a pointer-authentication related instruction. +struct PtrauthInstructionInfo { + bool IsAuthenticated; + bool IsLoad; + bool DoesBranch; +}; + +/// Get any pointer-authentication related information about the instruction +/// at address \p at_addr. +static llvm::Optional<PtrauthInstructionInfo> +GetPtrauthInstructionInfo(Target &target, const ArchSpec &arch, + const Address &at_addr) { + const char *plugin_name = nullptr; + const char *flavor = nullptr; + AddressRange range_bounds(at_addr, 4); + const bool prefer_file_cache = true; + DisassemblerSP disassembler_sp = Disassembler::DisassembleRange( + arch, plugin_name, flavor, target, range_bounds, prefer_file_cache); + if (!disassembler_sp) + return llvm::None; + + InstructionList &insn_list = disassembler_sp->GetInstructionList(); + InstructionSP insn = insn_list.GetInstructionAtIndex(0); + if (!insn) + return llvm::None; + + return PtrauthInstructionInfo{insn->IsAuthenticated(), insn->IsLoad(), + insn->DoesBranch()}; +} + +/// Describe the load address of \p addr using the format filename:line:col. +static void DescribeAddressBriefly(Stream &strm, const Address &addr, + Target &target) { + strm.Printf("at address=0x%" PRIx64, addr.GetLoadAddress(&target)); + StreamString s; + if (addr.GetDescription(s, target, eDescriptionLevelBrief)) + strm.Printf(" %s", s.GetString().data()); + strm.Printf(".\n"); +} + +bool StopInfoMachException::DeterminePtrauthFailure(ExecutionContext &exe_ctx) { + bool IsBreakpoint = m_value == 6; // EXC_BREAKPOINT + bool IsBadAccess = m_value == 1; // EXC_BAD_ACCESS + if (!IsBreakpoint && !IsBadAccess) + return false; + + // Check that we have a live process. + if (!exe_ctx.HasProcessScope() || !exe_ctx.HasThreadScope() || + !exe_ctx.HasTargetScope()) + return false; + + Thread &thread = *exe_ctx.GetThreadPtr(); + StackFrameSP current_frame = thread.GetStackFrameAtIndex(0); + if (!current_frame) + return false; + + Target &target = *exe_ctx.GetTargetPtr(); + Process &process = *exe_ctx.GetProcessPtr(); + ABISP abi_sp = process.GetABI(); + const ArchSpec &arch = target.GetArchitecture(); + assert(abi_sp && "Missing ABI info"); + + // Check for a ptrauth-enabled target. + const bool ptrauth_enabled_target = + arch.GetCore() == ArchSpec::eCore_arm_arm64e; + if (!ptrauth_enabled_target) + return false; + + // Set up a stream we can write a diagnostic into. + StreamString strm; + auto emit_ptrauth_prologue = [&](uint64_t at_address) { + strm.Printf("EXC_BAD_ACCESS (code=%" PRIu64 ", address=0x%" PRIx64 ")\n", + m_exc_code, at_address); + strm.Printf("Note: Possible pointer authentication failure detected.\n"); + }; + + // Check if we have a "brk 0xc47x" trap, where the value that failed to + // authenticate is in x16. + Address current_address = current_frame->GetFrameCodeAddress(); + if (IsBreakpoint) { + RegisterContext *reg_ctx = exe_ctx.GetRegisterContext(); + if (!reg_ctx) + return false; + + const RegisterInfo *X16Info = reg_ctx->GetRegisterInfoByName("x16"); + RegisterValue X16Val; + if (!reg_ctx->ReadRegister(X16Info, X16Val)) + return false; + uint64_t bad_address = X16Val.GetAsUInt64(); + + uint64_t fixed_bad_address = abi_sp->FixCodeAddress(bad_address); + Address brk_address; + if (!target.ResolveLoadAddress(fixed_bad_address, brk_address)) + return false; + + auto brk_ptrauth_info = + GetPtrauthInstructionInfo(target, arch, current_address); + if (brk_ptrauth_info && brk_ptrauth_info->IsAuthenticated) { + emit_ptrauth_prologue(bad_address); + strm.Printf("Found value that failed to authenticate "); + DescribeAddressBriefly(strm, brk_address, target); + m_description = std::string(strm.GetString()); + return true; + } + return false; + } + + assert(IsBadAccess && "Handle EXC_BAD_ACCESS only after this point"); + + // Check that we have the "bad address" from an EXC_BAD_ACCESS. + if (m_exc_data_count < 2) + return false; + + // Ok, we know the Target is valid and that it describes a ptrauth-enabled + // device. Now, we need to determine whether this exception was caused by a + // ptrauth failure. + + uint64_t bad_address = m_exc_subcode; + uint64_t fixed_bad_address = abi_sp->FixCodeAddress(bad_address); + uint64_t current_pc = current_address.GetLoadAddress(&target); + + // Detect: LDRAA, LDRAB (Load Register, with pointer authentication). + // + // If an authenticated load results in an exception, the instruction at the + // current PC should be one of LDRAx. + if (bad_address != current_pc && fixed_bad_address != current_pc) { + auto ptrauth_info = + GetPtrauthInstructionInfo(target, arch, current_address); + if (ptrauth_info && ptrauth_info->IsAuthenticated && ptrauth_info->IsLoad) { + emit_ptrauth_prologue(bad_address); + strm.Printf("Found authenticated load instruction "); + DescribeAddressBriefly(strm, current_address, target); + m_description = std::string(strm.GetString()); + return true; + } + } + + // Detect: BLRAA, BLRAAZ, BLRAB, BLRABZ (Branch with Link to Register, with + // pointer authentication). + // + // TODO: Detect: BRAA, BRAAZ, BRAB, BRABZ (Branch to Register, with pointer + // authentication). At a minimum, this requires call site info support for + // indirect calls. + // + // If an authenticated call or tail call results in an exception, stripping + // the bad address should give the current PC, which points to the address + // we tried to branch to. + if (bad_address != current_pc && fixed_bad_address == current_pc) { + if (StackFrameSP parent_frame = thread.GetStackFrameAtIndex(1)) { + addr_t return_pc = + parent_frame->GetFrameCodeAddress().GetLoadAddress(&target); + Address blr_address; + if (!target.ResolveLoadAddress(return_pc - 4, blr_address)) + return false; + + auto blr_ptrauth_info = + GetPtrauthInstructionInfo(target, arch, blr_address); + if (blr_ptrauth_info && blr_ptrauth_info->IsAuthenticated && + blr_ptrauth_info->DoesBranch) { + emit_ptrauth_prologue(bad_address); + strm.Printf("Found authenticated indirect branch "); + DescribeAddressBriefly(strm, blr_address, target); + m_description = std::string(strm.GetString()); + return true; + } + } + } + + // TODO: Detect: RETAA, RETAB (Return from subroutine, with pointer + // authentication). + // + // Is there a motivating, non-malicious code snippet that corrupts LR? + + return false; +} + const char *StopInfoMachException::GetDescription() { if (!m_description.empty()) return m_description.c_str(); @@ -79,6 +256,11 @@ const char *StopInfoMachException::GetDescription() { } break; + case llvm::Triple::aarch64: + if (DeterminePtrauthFailure(exe_ctx)) + return m_description.c_str(); + break; + default: break; } @@ -190,6 +372,11 @@ const char *StopInfoMachException::GetDescription() { } break; + case llvm::Triple::aarch64: + if (DeterminePtrauthFailure(exe_ctx)) + return m_description.c_str(); + break; + default: break; } diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/StopInfoMachException.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/StopInfoMachException.h index d9c1886d7096..6467745a7bf2 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/StopInfoMachException.h +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/StopInfoMachException.h @@ -16,6 +16,11 @@ namespace lldb_private { class StopInfoMachException : public StopInfo { + /// Determine the pointer-authentication related failure that caused this + /// exception. Returns true and fills out the failure description if there + /// is auth-related failure, and returns false otherwise. + bool DeterminePtrauthFailure(ExecutionContext &exe_ctx); + public: // Constructors and Destructors StopInfoMachException(Thread &thread, uint32_t exc_type, diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/lldb-mips-freebsd-register-enums.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/lldb-mips-freebsd-register-enums.h index e6a7efd00f67..000f6e3847e7 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/lldb-mips-freebsd-register-enums.h +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/lldb-mips-freebsd-register-enums.h @@ -57,9 +57,47 @@ enum { gpr_dummy_mips64, k_last_gpr_mips64 = gpr_dummy_mips64, + k_first_fpr_mips64, + fpr_f0_mips64 = k_first_fpr_mips64, + fpr_f1_mips64, + fpr_f2_mips64, + fpr_f3_mips64, + fpr_f4_mips64, + fpr_f5_mips64, + fpr_f6_mips64, + fpr_f7_mips64, + fpr_f8_mips64, + fpr_f9_mips64, + fpr_f10_mips64, + fpr_f11_mips64, + fpr_f12_mips64, + fpr_f13_mips64, + fpr_f14_mips64, + fpr_f15_mips64, + fpr_f16_mips64, + fpr_f17_mips64, + fpr_f18_mips64, + fpr_f19_mips64, + fpr_f20_mips64, + fpr_f21_mips64, + fpr_f22_mips64, + fpr_f23_mips64, + fpr_f24_mips64, + fpr_f25_mips64, + fpr_f26_mips64, + fpr_f27_mips64, + fpr_f28_mips64, + fpr_f29_mips64, + fpr_f30_mips64, + fpr_f31_mips64, + fpr_fcsr_mips64, + fpr_fir_mips64, + k_last_fpr_mips64 = fpr_fir_mips64, + k_num_registers_mips64, - k_num_gpr_registers_mips64 = k_last_gpr_mips64 - k_first_gpr_mips64 + 1 + k_num_gpr_registers_mips64 = k_last_gpr_mips64 - k_first_gpr_mips64 + 1, + k_num_fpr_registers_mips64 = k_last_fpr_mips64 - k_first_fpr_mips64 + 1, }; -} +} // namespace lldb_private #endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_LLDB_MIPS_FREEBSD_REGISTER_ENUMS_H diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp index 12bc7390c729..23b346d5c17f 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp @@ -37,12 +37,7 @@ namespace ELF = llvm::ELF; LLDB_PLUGIN_DEFINE(ProcessElfCore) -ConstString ProcessElfCore::GetPluginNameStatic() { - static ConstString g_name("elf-core"); - return g_name; -} - -const char *ProcessElfCore::GetPluginDescriptionStatic() { +llvm::StringRef ProcessElfCore::GetPluginDescriptionStatic() { return "ELF core dump plug-in."; } @@ -110,11 +105,6 @@ ProcessElfCore::~ProcessElfCore() { Finalize(); } -// PluginInterface -ConstString ProcessElfCore::GetPluginName() { return GetPluginNameStatic(); } - -uint32_t ProcessElfCore::GetPluginVersion() { return 1; } - lldb::addr_t ProcessElfCore::AddAddressRangeFromLoadSegment( const elf::ELFProgramHeader &header) { const lldb::addr_t addr = header.p_vaddr; @@ -257,7 +247,7 @@ Status ProcessElfCore::DoLoadCore() { lldb_private::DynamicLoader *ProcessElfCore::GetDynamicLoader() { if (m_dyld_up.get() == nullptr) m_dyld_up.reset(DynamicLoader::FindPlugin( - this, DynamicLoaderPOSIXDYLD::GetPluginNameStatic().GetCString())); + this, DynamicLoaderPOSIXDYLD::GetPluginNameStatic())); return m_dyld_up.get(); } @@ -291,8 +281,8 @@ size_t ProcessElfCore::ReadMemory(lldb::addr_t addr, void *buf, size_t size, return DoReadMemory(addr, buf, size, error); } -Status ProcessElfCore::GetMemoryRegionInfo(lldb::addr_t load_addr, - MemoryRegionInfo ®ion_info) { +Status ProcessElfCore::DoGetMemoryRegionInfo(lldb::addr_t load_addr, + MemoryRegionInfo ®ion_info) { region_info.Clear(); const VMRangeToPermissions::Entry *permission_entry = m_core_range_infos.FindEntryThatContainsOrFollows(load_addr); @@ -519,9 +509,8 @@ ProcessElfCore::parseSegment(const DataExtractor &segment) { size_t note_start = offset; size_t note_size = llvm::alignTo(note.n_descsz, 4); - DataExtractor note_data(segment, note_start, note_size); - result.push_back({note, note_data}); + result.push_back({note, DataExtractor(segment, note_start, note_size)}); offset += note_size; } @@ -897,7 +886,8 @@ llvm::Error ProcessElfCore::parseLinuxNotes(llvm::ArrayRef<CoreNote> notes) { /// A note segment consists of one or more NOTE entries, but their types and /// meaning differ depending on the OS. llvm::Error ProcessElfCore::ParseThreadContextsFromNoteSegment( - const elf::ELFProgramHeader &segment_header, DataExtractor segment_data) { + const elf::ELFProgramHeader &segment_header, + const DataExtractor &segment_data) { assert(segment_header.p_type == llvm::ELF::PT_NOTE); auto notes_or_error = parseSegment(segment_data); diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/ProcessElfCore.h b/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/ProcessElfCore.h index d8e3cc9ae3e1..fd36e5027816 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/ProcessElfCore.h +++ b/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/ProcessElfCore.h @@ -40,9 +40,9 @@ public: static void Terminate(); - static lldb_private::ConstString GetPluginNameStatic(); + static llvm::StringRef GetPluginNameStatic() { return "elf-core"; } - static const char *GetPluginDescriptionStatic(); + static llvm::StringRef GetPluginDescriptionStatic(); // Constructors and Destructors ProcessElfCore(lldb::TargetSP target_sp, lldb::ListenerSP listener_sp, @@ -60,9 +60,7 @@ public: lldb_private::DynamicLoader *GetDynamicLoader() override; // PluginInterface protocol - lldb_private::ConstString GetPluginName() override; - - uint32_t GetPluginVersion() override; + llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); } // Process Control lldb_private::Status DoDestroy() override; @@ -71,9 +69,8 @@ public: lldb_private::Status WillResume() override { lldb_private::Status error; - error.SetErrorStringWithFormat( - "error: %s does not support resuming processes", - GetPluginName().GetCString()); + error.SetErrorStringWithFormatv( + "error: {0} does not support resuming processes", GetPluginName()); return error; } @@ -89,10 +86,6 @@ public: size_t DoReadMemory(lldb::addr_t addr, void *buf, size_t size, lldb_private::Status &error) override; - lldb_private::Status - GetMemoryRegionInfo(lldb::addr_t load_addr, - lldb_private::MemoryRegionInfo ®ion_info) override; - lldb::addr_t GetImageInfoAddress() override; lldb_private::ArchSpec GetArchitecture(); @@ -108,6 +101,10 @@ protected: bool DoUpdateThreadList(lldb_private::ThreadList &old_thread_list, lldb_private::ThreadList &new_thread_list) override; + lldb_private::Status + DoGetMemoryRegionInfo(lldb::addr_t load_addr, + lldb_private::MemoryRegionInfo ®ion_info) override; + private: struct NT_FILE_Entry { lldb::addr_t start; @@ -148,7 +145,7 @@ private: // Parse thread(s) data structures(prstatus, prpsinfo) from given NOTE segment llvm::Error ParseThreadContextsFromNoteSegment( const elf::ELFProgramHeader &segment_header, - lldb_private::DataExtractor segment_data); + const lldb_private::DataExtractor &segment_data); // Returns number of thread contexts stored in the core file uint32_t GetNumThreadContexts(); diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/RegisterUtilities.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/RegisterUtilities.cpp index 0c21c0f50abb..6f3bf02cd303 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/RegisterUtilities.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/RegisterUtilities.cpp @@ -34,5 +34,5 @@ DataExtractor lldb_private::getRegset(llvm::ArrayRef<CoreNote> Notes, uint32_t Type = *TypeOr; auto Iter = llvm::find_if( Notes, [Type](const CoreNote &Note) { return Note.info.n_type == Type; }); - return Iter == Notes.end() ? DataExtractor() : Iter->data; + return Iter == Notes.end() ? DataExtractor() : DataExtractor(Iter->data); } diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteClientBase.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteClientBase.cpp index a4c71e864a76..803e5842cd7d 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteClientBase.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteClientBase.cpp @@ -249,32 +249,6 @@ GDBRemoteClientBase::SendPacketAndWaitForResponseNoLock( return packet_result; } -bool GDBRemoteClientBase::SendvContPacket( - llvm::StringRef payload, std::chrono::seconds interrupt_timeout, - StringExtractorGDBRemote &response) { - Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS)); - LLDB_LOGF(log, "GDBRemoteCommunicationClient::%s ()", __FUNCTION__); - - // we want to lock down packet sending while we continue - Lock lock(*this, interrupt_timeout); - - LLDB_LOGF(log, - "GDBRemoteCommunicationClient::%s () sending vCont packet: %.*s", - __FUNCTION__, int(payload.size()), payload.data()); - - if (SendPacketNoLock(payload) != PacketResult::Success) - return false; - - OnRunPacketSent(true); - - // wait for the response to the vCont - if (ReadPacket(response, llvm::None, false) == PacketResult::Success) { - if (response.IsOKResponse()) - return true; - } - - return false; -} bool GDBRemoteClientBase::ShouldStop(const UnixSignals &signals, StringExtractorGDBRemote &response) { std::lock_guard<std::mutex> lock(m_mutex); diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteClientBase.h b/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteClientBase.h index 518b81318b6c..43a5313eae6a 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteClientBase.h +++ b/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteClientBase.h @@ -59,10 +59,6 @@ public: std::chrono::seconds interrupt_timeout, llvm::function_ref<void(llvm::StringRef)> output_callback); - bool SendvContPacket(llvm::StringRef payload, - std::chrono::seconds interrupt_timeout, - StringExtractorGDBRemote &response); - class Lock { public: // If interrupt_timeout == 0 seconds, only take the lock if the target is diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp index 013d407c0fc1..4ce79da48f07 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp @@ -22,7 +22,6 @@ #include "lldb/Host/Pipe.h" #include "lldb/Host/ProcessLaunchInfo.h" #include "lldb/Host/Socket.h" -#include "lldb/Host/StringConvert.h" #include "lldb/Host/ThreadLauncher.h" #include "lldb/Host/common/TCPSocket.h" #include "lldb/Host/posix/ConnectionFileDescriptorPosix.h" @@ -102,7 +101,7 @@ size_t GDBRemoteCommunication::SendAck() { Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PACKETS)); ConnectionStatus status = eConnectionStatusSuccess; char ch = '+'; - const size_t bytes_written = Write(&ch, 1, status, nullptr); + const size_t bytes_written = WriteAll(&ch, 1, status, nullptr); LLDB_LOGF(log, "<%4" PRIu64 "> send packet: %c", (uint64_t)bytes_written, ch); m_history.AddPacket(ch, GDBRemotePacket::ePacketTypeSend, bytes_written); return bytes_written; @@ -112,7 +111,7 @@ size_t GDBRemoteCommunication::SendNack() { Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PACKETS)); ConnectionStatus status = eConnectionStatusSuccess; char ch = '-'; - const size_t bytes_written = Write(&ch, 1, status, nullptr); + const size_t bytes_written = WriteAll(&ch, 1, status, nullptr); LLDB_LOGF(log, "<%4" PRIu64 "> send packet: %c", (uint64_t)bytes_written, ch); m_history.AddPacket(ch, GDBRemotePacket::ePacketTypeSend, bytes_written); return bytes_written; @@ -138,7 +137,7 @@ GDBRemoteCommunication::SendRawPacketNoLock(llvm::StringRef packet, ConnectionStatus status = eConnectionStatusSuccess; const char *packet_data = packet.data(); const size_t packet_length = packet.size(); - size_t bytes_written = Write(packet_data, packet_length, status, nullptr); + size_t bytes_written = WriteAll(packet_data, packet_length, status, nullptr); if (log) { size_t binary_start_offset = 0; if (strncmp(packet_data, "$vFile:pwrite:", strlen("$vFile:pwrite:")) == @@ -894,8 +893,13 @@ GDBRemoteCommunication::ListenThread(lldb::thread_arg_t arg) { if (connection) { // Do the listen on another thread so we can continue on... - if (connection->Connect(comm->m_listen_url.c_str(), &error) != - eConnectionStatusSuccess) + if (connection->Connect( + comm->m_listen_url.c_str(), [comm](llvm::StringRef port_str) { + uint16_t port = 0; + llvm::to_integer(port_str, port, 10); + comm->m_port_promise.set_value(port); + }, + &error) != eConnectionStatusSuccess) comm->SetConnection(nullptr); } return {}; @@ -1057,10 +1061,12 @@ Status GDBRemoteCommunication::StartDebugserverProcess( return error; } - ConnectionFileDescriptor *connection = - (ConnectionFileDescriptor *)GetConnection(); // Wait for 10 seconds to resolve the bound port - uint16_t port_ = connection->GetListeningPort(std::chrono::seconds(10)); + std::future<uint16_t> port_future = m_port_promise.get_future(); + uint16_t port_ = port_future.wait_for(std::chrono::seconds(10)) == + std::future_status::ready + ? port_future.get() + : 0; if (port_ > 0) { char port_cstr[32]; snprintf(port_cstr, sizeof(port_cstr), "127.0.0.1:%i", port_); @@ -1173,7 +1179,9 @@ Status GDBRemoteCommunication::StartDebugserverProcess( port_cstr, num_bytes, std::chrono::seconds{10}, num_bytes); if (error.Success() && (port != nullptr)) { assert(num_bytes > 0 && port_cstr[num_bytes - 1] == '\0'); - uint16_t child_port = StringConvert::ToUInt32(port_cstr, 0); + uint16_t child_port = 0; + // FIXME: improve error handling + llvm::to_integer(port_cstr, child_port); if (*port == 0 || *port == child_port) { *port = child_port; LLDB_LOGF(log, diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h b/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h index b1e2075a64fe..5da568e9b4d4 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h +++ b/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h @@ -12,6 +12,7 @@ #include "GDBRemoteCommunicationHistory.h" #include <condition_variable> +#include <future> #include <mutex> #include <queue> #include <string> @@ -51,6 +52,32 @@ enum class CompressionType { LZMA, // Lempel–Ziv–Markov chain algorithm }; +// Data included in the vFile:fstat packet. +// https://sourceware.org/gdb/onlinedocs/gdb/struct-stat.html#struct-stat +struct GDBRemoteFStatData { + llvm::support::ubig32_t gdb_st_dev; + llvm::support::ubig32_t gdb_st_ino; + llvm::support::ubig32_t gdb_st_mode; + llvm::support::ubig32_t gdb_st_nlink; + llvm::support::ubig32_t gdb_st_uid; + llvm::support::ubig32_t gdb_st_gid; + llvm::support::ubig32_t gdb_st_rdev; + llvm::support::ubig64_t gdb_st_size; + llvm::support::ubig64_t gdb_st_blksize; + llvm::support::ubig64_t gdb_st_blocks; + llvm::support::ubig32_t gdb_st_atime; + llvm::support::ubig32_t gdb_st_mtime; + llvm::support::ubig32_t gdb_st_ctime; +}; +static_assert(sizeof(GDBRemoteFStatData) == 64, + "size of GDBRemoteFStatData is not 64"); + +enum GDBErrno { +#define HANDLE_ERRNO(name, value) GDB_##name = value, +#include "Plugins/Process/gdb-remote/GDBRemoteErrno.def" + GDB_EUNKNOWN = 9999 +}; + class ProcessGDBRemote; class GDBRemoteCommunication : public Communication { @@ -217,6 +244,8 @@ private: std::mutex m_packet_queue_mutex; // Mutex for accessing queue std::condition_variable m_condition_queue_not_empty; // Condition variable to wait for packets + // Promise used to grab the port number from listening thread + std::promise<uint16_t> m_port_promise; HostThread m_listen_thread; std::string m_listen_url; diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp index b16aed4f5c90..78e722eee080 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp @@ -16,7 +16,6 @@ #include "lldb/Core/ModuleSpec.h" #include "lldb/Host/HostInfo.h" -#include "lldb/Host/StringConvert.h" #include "lldb/Host/XML.h" #include "lldb/Symbol/Symbol.h" #include "lldb/Target/MemoryRegionInfo.h" @@ -65,6 +64,8 @@ GDBRemoteCommunicationClient::GDBRemoteCommunicationClient() m_supports_QEnvironmentHexEncoded(true), m_supports_qSymbol(true), m_qSymbol_requests_done(false), m_supports_qModuleInfo(true), m_supports_jThreadsInfo(true), m_supports_jModulesInfo(true), + m_supports_vFileSize(true), m_supports_vFileMode(true), + m_supports_vFileExists(true), m_supports_vRun(true), m_host_arch(), m_process_arch(), m_os_build(), m_os_kernel(), m_hostname(), m_gdb_server_name(), m_default_packet_timeout(0), @@ -82,6 +83,8 @@ bool GDBRemoteCommunicationClient::HandshakeWithServer(Status *error_ptr) { // Start the read thread after we send the handshake ack since if we fail to // send the handshake ack, there is no reason to continue... + std::chrono::steady_clock::time_point start_of_handshake = + std::chrono::steady_clock::now(); if (SendAck()) { // Wait for any responses that might have been queued up in the remote // GDB server and flush them all @@ -97,8 +100,24 @@ bool GDBRemoteCommunicationClient::HandshakeWithServer(Status *error_ptr) { if (QueryNoAckModeSupported()) { return true; } else { - if (error_ptr) - error_ptr->SetErrorString("failed to get reply to handshake packet"); + std::chrono::steady_clock::time_point end_of_handshake = + std::chrono::steady_clock::now(); + auto handshake_timeout = + std::chrono::duration<double>(end_of_handshake - start_of_handshake) + .count(); + if (error_ptr) { + if (packet_result == PacketResult::ErrorDisconnected) + error_ptr->SetErrorString("Connection shut down by remote side " + "while waiting for reply to initial " + "handshake packet"); + else if (packet_result == PacketResult::ErrorReplyTimeout) + error_ptr->SetErrorStringWithFormat( + "failed to get reply to handshake packet within timeout of " + "%.1f seconds", + handshake_timeout); + else + error_ptr->SetErrorString("failed to get reply to handshake packet"); + } } } else { if (error_ptr) @@ -257,12 +276,14 @@ void GDBRemoteCommunicationClient::ResetDiscoverableSettings(bool did_exec) { m_attach_or_wait_reply = eLazyBoolCalculate; m_avoid_g_packets = eLazyBoolCalculate; m_supports_multiprocess = eLazyBoolCalculate; + m_supports_qSaveCore = eLazyBoolCalculate; m_supports_qXfer_auxv_read = eLazyBoolCalculate; m_supports_qXfer_libraries_read = eLazyBoolCalculate; m_supports_qXfer_libraries_svr4_read = eLazyBoolCalculate; m_supports_qXfer_features_read = eLazyBoolCalculate; m_supports_qXfer_memory_map_read = eLazyBoolCalculate; m_supports_augmented_libraries_svr4_read = eLazyBoolCalculate; + m_uses_native_signals = eLazyBoolCalculate; m_supports_qProcessInfoPID = true; m_supports_qfProcessInfo = true; m_supports_qUserName = true; @@ -312,13 +333,16 @@ void GDBRemoteCommunicationClient::GetRemoteQSupported() { m_supports_qEcho = eLazyBoolNo; m_supports_QPassSignals = eLazyBoolNo; m_supports_memory_tagging = eLazyBoolNo; + m_supports_qSaveCore = eLazyBoolNo; + m_uses_native_signals = eLazyBoolNo; m_max_packet_size = UINT64_MAX; // It's supposed to always be there, but if // not, we assume no limit // build the qSupported packet std::vector<std::string> features = {"xmlRegisters=i386,arm,mips,arc", - "multiprocess+"}; + "multiprocess+", "fork-events+", + "vfork-events+"}; StreamString packet; packet.PutCString("qSupported"); for (uint32_t i = 0; i < features.size(); ++i) { @@ -333,10 +357,7 @@ void GDBRemoteCommunicationClient::GetRemoteQSupported() { // configuration of the transport before attaching/launching the process. m_qSupported_response = response.GetStringRef().str(); - llvm::SmallVector<llvm::StringRef, 16> server_features; - response.GetStringRef().split(server_features, ';'); - - for (llvm::StringRef x : server_features) { + for (llvm::StringRef x : llvm::split(response.GetStringRef(), ';')) { if (x == "qXfer:auxv:read+") m_supports_qXfer_auxv_read = eLazyBoolYes; else if (x == "qXfer:libraries-svr4:read+") @@ -358,6 +379,10 @@ void GDBRemoteCommunicationClient::GetRemoteQSupported() { m_supports_multiprocess = eLazyBoolYes; else if (x == "memory-tagging+") m_supports_memory_tagging = eLazyBoolYes; + else if (x == "qSaveCore+") + m_supports_qSaveCore = eLazyBoolYes; + else if (x == "native-signals+") + m_uses_native_signals = eLazyBoolYes; // Look for a list of compressions in the features list e.g. // qXfer:features:read+;PacketSize=20000;qEcho+;SupportedCompressions=zlib- // deflate,lzma @@ -500,6 +525,10 @@ LazyBool GDBRemoteCommunicationClient::GetThreadPacketSupported( return eLazyBoolNo; } +bool GDBRemoteCommunicationClient::GetSaveCoreSupported() const { + return m_supports_qSaveCore == eLazyBoolYes; +} + StructuredData::ObjectSP GDBRemoteCommunicationClient::GetThreadsInfo() { // Get information on all threads at one using the "jThreadsInfo" packet StructuredData::ObjectSP object_sp; @@ -661,54 +690,6 @@ bool GDBRemoteCommunicationClient::GetxPacketSupported() { return m_supports_x; } -GDBRemoteCommunicationClient::PacketResult -GDBRemoteCommunicationClient::SendPacketsAndConcatenateResponses( - const char *payload_prefix, std::string &response_string) { - Lock lock(*this); - if (!lock) { - Log *log(ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet(GDBR_LOG_PROCESS | - GDBR_LOG_PACKETS)); - LLDB_LOGF(log, - "error: failed to get packet sequence mutex, not sending " - "packets with prefix '%s'", - payload_prefix); - return PacketResult::ErrorNoSequenceLock; - } - - response_string = ""; - std::string payload_prefix_str(payload_prefix); - unsigned int response_size = 0x1000; - if (response_size > GetRemoteMaxPacketSize()) { // May send qSupported packet - response_size = GetRemoteMaxPacketSize(); - } - - for (unsigned int offset = 0; true; offset += response_size) { - StringExtractorGDBRemote this_response; - // Construct payload - char sizeDescriptor[128]; - snprintf(sizeDescriptor, sizeof(sizeDescriptor), "%x,%x", offset, - response_size); - PacketResult result = SendPacketAndWaitForResponseNoLock( - payload_prefix_str + sizeDescriptor, this_response); - if (result != PacketResult::Success) - return result; - - const std::string &this_string = std::string(this_response.GetStringRef()); - - // Check for m or l as first character; l seems to mean this is the last - // chunk - char first_char = *this_string.c_str(); - if (first_char != 'm' && first_char != 'l') { - return PacketResult::ErrorReplyInvalid; - } - // Concatenate the result so far (skipping 'm' or 'l') - response_string.append(this_string, 1, std::string::npos); - if (first_char == 'l') - // We're done - return PacketResult::Success; - } -} - lldb::pid_t GDBRemoteCommunicationClient::GetCurrentProcessID(bool allow_lazy) { if (allow_lazy && m_curr_pid_is_valid == eLazyBoolYes) return m_curr_pid; @@ -765,6 +746,11 @@ bool GDBRemoteCommunicationClient::GetLaunchSuccess(std::string &error_str) { PacketResult::Success) { if (response.IsOKResponse()) return true; + // GDB does not implement qLaunchSuccess -- but if we used vRun, + // then we already received a successful launch indication via stop + // reason. + if (response.IsUnsupportedResponse() && m_supports_vRun) + return true; if (response.GetChar() == 'E') { // A string the describes what failed when launching... error_str = std::string(response.GetStringRef().substr(1)); @@ -803,6 +789,36 @@ int GDBRemoteCommunicationClient::SendArgumentsPacket( } } if (!argv.empty()) { + // try vRun first + if (m_supports_vRun) { + StreamString packet; + packet.PutCString("vRun"); + for (const char *arg : argv) { + packet.PutChar(';'); + packet.PutBytesAsRawHex8(arg, strlen(arg)); + } + + StringExtractorGDBRemote response; + if (SendPacketAndWaitForResponse(packet.GetString(), response) != + PacketResult::Success) + return -1; + + if (response.IsErrorResponse()) { + uint8_t error = response.GetError(); + if (error) + return error; + return -1; + } + // vRun replies with a stop reason packet + // FIXME: right now we just discard the packet and LLDB queries + // for stop reason again + if (!response.IsUnsupportedResponse()) + return 0; + + m_supports_vRun = false; + } + + // fallback to A StreamString packet; packet.PutChar('A'); for (size_t i = 0, n = argv.size(); i < n; ++i) { @@ -839,7 +855,6 @@ int GDBRemoteCommunicationClient::SendEnvironment(const Environment &env) { int GDBRemoteCommunicationClient::SendEnvironmentPacket( char const *name_equal_value) { if (name_equal_value && name_equal_value[0]) { - StreamString packet; bool send_hex_encoding = false; for (const char *p = name_equal_value; *p != '\0' && !send_hex_encoding; ++p) { @@ -861,33 +876,43 @@ int GDBRemoteCommunicationClient::SendEnvironmentPacket( } StringExtractorGDBRemote response; - if (send_hex_encoding) { - if (m_supports_QEnvironmentHexEncoded) { - packet.PutCString("QEnvironmentHexEncoded:"); - packet.PutBytesAsRawHex8(name_equal_value, strlen(name_equal_value)); - if (SendPacketAndWaitForResponse(packet.GetString(), response) == - PacketResult::Success) { - if (response.IsOKResponse()) - return 0; - uint8_t error = response.GetError(); - if (error) - return error; - if (response.IsUnsupportedResponse()) - m_supports_QEnvironmentHexEncoded = false; - } + // Prefer sending unencoded, if possible and the server supports it. + if (!send_hex_encoding && m_supports_QEnvironment) { + StreamString packet; + packet.Printf("QEnvironment:%s", name_equal_value); + if (SendPacketAndWaitForResponse(packet.GetString(), response) != + PacketResult::Success) + return -1; + + if (response.IsOKResponse()) + return 0; + if (response.IsUnsupportedResponse()) + m_supports_QEnvironment = false; + else { + uint8_t error = response.GetError(); + if (error) + return error; + return -1; } + } - } else if (m_supports_QEnvironment) { - packet.Printf("QEnvironment:%s", name_equal_value); - if (SendPacketAndWaitForResponse(packet.GetString(), response) == - PacketResult::Success) { - if (response.IsOKResponse()) - return 0; + if (m_supports_QEnvironmentHexEncoded) { + StreamString packet; + packet.PutCString("QEnvironmentHexEncoded:"); + packet.PutBytesAsRawHex8(name_equal_value, strlen(name_equal_value)); + if (SendPacketAndWaitForResponse(packet.GetString(), response) != + PacketResult::Success) + return -1; + + if (response.IsOKResponse()) + return 0; + if (response.IsUnsupportedResponse()) + m_supports_QEnvironmentHexEncoded = false; + else { uint8_t error = response.GetError(); if (error) return error; - if (response.IsUnsupportedResponse()) - m_supports_QEnvironment = false; + return -1; } } } @@ -949,26 +974,21 @@ llvm::VersionTuple GDBRemoteCommunicationClient::GetMacCatalystVersion() { return m_maccatalyst_version; } -bool GDBRemoteCommunicationClient::GetOSBuildString(std::string &s) { +llvm::Optional<std::string> GDBRemoteCommunicationClient::GetOSBuildString() { if (GetHostInfo()) { - if (!m_os_build.empty()) { - s = m_os_build; - return true; - } + if (!m_os_build.empty()) + return m_os_build; } - s.clear(); - return false; + return llvm::None; } -bool GDBRemoteCommunicationClient::GetOSKernelDescription(std::string &s) { +llvm::Optional<std::string> +GDBRemoteCommunicationClient::GetOSKernelDescription() { if (GetHostInfo()) { - if (!m_os_kernel.empty()) { - s = m_os_kernel; - return true; - } + if (!m_os_kernel.empty()) + return m_os_kernel; } - s.clear(); - return false; + return llvm::None; } bool GDBRemoteCommunicationClient::GetHostname(std::string &s) { @@ -1093,9 +1113,8 @@ void GDBRemoteCommunicationClient::MaybeEnableCompression( if (avail_type != CompressionType::None) { StringExtractorGDBRemote response; - llvm::Twine packet = "QEnableCompression:type:" + avail_name + ";"; - if (SendPacketAndWaitForResponse(packet.str(), response) != - PacketResult::Success) + std::string packet = "QEnableCompression:type:" + avail_name.str() + ";"; + if (SendPacketAndWaitForResponse(packet, response) != PacketResult::Success) return; if (response.IsOKResponse()) { @@ -1360,24 +1379,6 @@ bool GDBRemoteCommunicationClient::GetHostInfo(bool force) { return m_qHostInfo_is_valid == eLazyBoolYes; } -int GDBRemoteCommunicationClient::SendAttach( - lldb::pid_t pid, StringExtractorGDBRemote &response) { - if (pid != LLDB_INVALID_PROCESS_ID) { - char packet[64]; - const int packet_len = - ::snprintf(packet, sizeof(packet), "vAttach;%" PRIx64, pid); - UNUSED_IF_ASSERT_DISABLED(packet_len); - assert(packet_len < (int)sizeof(packet)); - if (SendPacketAndWaitForResponse(packet, response) == - PacketResult::Success) { - if (response.IsErrorResponse()) - return response.GetError(); - return 0; - } - } - return -1; -} - int GDBRemoteCommunicationClient::SendStdinNotification(const char *data, size_t data_len) { StreamString packet; @@ -1457,9 +1458,12 @@ bool GDBRemoteCommunicationClient::DeallocateMemory(addr_t addr) { return false; } -Status GDBRemoteCommunicationClient::Detach(bool keep_stopped) { +Status GDBRemoteCommunicationClient::Detach(bool keep_stopped, + lldb::pid_t pid) { Status error; + lldb_private::StreamString packet; + packet.PutChar('D'); if (keep_stopped) { if (m_supports_detach_stay_stopped == eLazyBoolCalculate) { char packet[64]; @@ -1481,17 +1485,27 @@ Status GDBRemoteCommunicationClient::Detach(bool keep_stopped) { error.SetErrorString("Stays stopped not supported by this target."); return error; } else { - StringExtractorGDBRemote response; - PacketResult packet_result = SendPacketAndWaitForResponse("D1", response); - if (packet_result != PacketResult::Success) - error.SetErrorString("Sending extended disconnect packet failed."); + packet.PutChar('1'); } - } else { - StringExtractorGDBRemote response; - PacketResult packet_result = SendPacketAndWaitForResponse("D", response); - if (packet_result != PacketResult::Success) - error.SetErrorString("Sending disconnect packet failed."); } + + if (m_supports_multiprocess) { + // Some servers (e.g. qemu) require specifying the PID even if only a single + // process is running. + if (pid == LLDB_INVALID_PROCESS_ID) + pid = GetCurrentProcessID(); + packet.PutChar(';'); + packet.PutHex64(pid); + } else if (pid != LLDB_INVALID_PROCESS_ID) { + error.SetErrorString("Multiprocess extension not supported by the server."); + return error; + } + + StringExtractorGDBRemote response; + PacketResult packet_result = + SendPacketAndWaitForResponse(packet.GetString(), response); + if (packet_result != PacketResult::Success) + error.SetErrorString("Sending isconnect packet failed."); return error; } @@ -1527,17 +1541,17 @@ Status GDBRemoteCommunicationClient::GetMemoryRegionInfo( region_info.GetRange().IsValid()) { saw_permissions = true; if (region_info.GetRange().Contains(addr)) { - if (value.find('r') != llvm::StringRef::npos) + if (value.contains('r')) region_info.SetReadable(MemoryRegionInfo::eYes); else region_info.SetReadable(MemoryRegionInfo::eNo); - if (value.find('w') != llvm::StringRef::npos) + if (value.contains('w')) region_info.SetWritable(MemoryRegionInfo::eYes); else region_info.SetWritable(MemoryRegionInfo::eNo); - if (value.find('x') != llvm::StringRef::npos) + if (value.contains('x')) region_info.SetExecutable(MemoryRegionInfo::eYes); else region_info.SetExecutable(MemoryRegionInfo::eNo); @@ -1572,6 +1586,19 @@ Status GDBRemoteCommunicationClient::GetMemoryRegionInfo( } } } + } else if (name.equals("type")) { + std::string comma_sep_str = value.str(); + size_t comma_pos; + while ((comma_pos = comma_sep_str.find(',')) != std::string::npos) { + comma_sep_str[comma_pos] = '\0'; + if (comma_sep_str == "stack") { + region_info.SetIsStackMemory(MemoryRegionInfo::eYes); + } + } + // handle final (or only) type of "stack" + if (comma_sep_str == "stack") { + region_info.SetIsStackMemory(MemoryRegionInfo::eYes); + } } else if (name.equals("error")) { StringExtractorGDBRemote error_extractor(value); std::string error_string; @@ -1580,21 +1607,12 @@ Status GDBRemoteCommunicationClient::GetMemoryRegionInfo( error.SetErrorString(error_string.c_str()); } else if (name.equals("dirty-pages")) { std::vector<addr_t> dirty_page_list; - std::string comma_sep_str = value.str(); - size_t comma_pos; - addr_t page; - while ((comma_pos = comma_sep_str.find(',')) != std::string::npos) { - comma_sep_str[comma_pos] = '\0'; - page = StringConvert::ToUInt64(comma_sep_str.c_str(), - LLDB_INVALID_ADDRESS, 16); - if (page != LLDB_INVALID_ADDRESS) + for (llvm::StringRef x : llvm::split(value, ',')) { + addr_t page; + x.consume_front("0x"); + if (llvm::to_integer(x, page, 16)) dirty_page_list.push_back(page); - comma_sep_str.erase(0, comma_pos + 1); } - page = StringConvert::ToUInt64(comma_sep_str.c_str(), - LLDB_INVALID_ADDRESS, 16); - if (page != LLDB_INVALID_ADDRESS) - dirty_page_list.push_back(page); region_info.SetDirtyPageList(dirty_page_list); } } @@ -1683,17 +1701,13 @@ Status GDBRemoteCommunicationClient::LoadQXferMemoryMap() { return error; } - std::string xml; - lldb_private::Status lldberr; - if (!ReadExtFeature(ConstString("memory-map"), ConstString(""), xml, - lldberr)) { - error.SetErrorString("Failed to read memory map"); - return error; - } + llvm::Expected<std::string> xml = ReadExtFeature("memory-map", ""); + if (!xml) + return Status(xml.takeError()); XMLDocument xml_document; - if (!xml_document.ParseMemory(xml.c_str(), xml.size())) { + if (!xml_document.ParseMemory(xml->c_str(), xml->size())) { error.SetErrorString("Failed to parse memory map xml"); return error; } @@ -2358,24 +2372,6 @@ bool GDBRemoteCommunicationClient::GetGroupName(uint32_t gid, return false; } -bool GDBRemoteCommunicationClient::SetNonStopMode(const bool enable) { - // Form non-stop packet request - char packet[32]; - const int packet_len = - ::snprintf(packet, sizeof(packet), "QNonStop:%1d", (int)enable); - assert(packet_len < (int)sizeof(packet)); - UNUSED_IF_ASSERT_DISABLED(packet_len); - - StringExtractorGDBRemote response; - // Send to target - if (SendPacketAndWaitForResponse(packet, response) == PacketResult::Success) - if (response.IsOKResponse()) - return true; - - // Failed or not supported - return false; -} - static void MakeSpeedTestPacket(StreamString &packet, uint32_t send_size, uint32_t recv_size) { packet.Clear(); @@ -2827,8 +2823,12 @@ GDBRemoteCommunicationClient::GetCurrentProcessAndThreadIDs( if (ch == 'm') { do { auto pid_tid = response.GetPidTid(LLDB_INVALID_PROCESS_ID); + // If we get an invalid response, break out of the loop. + // If there are valid tids, they have been added to ids. + // If there are no valid tids, we'll fall through to the + // bare-iron target handling below. if (!pid_tid) - return {}; + break; ids.push_back(pid_tid.getValue()); ch = response.GetChar(); // Skip the command separator @@ -2959,7 +2959,7 @@ Status GDBRemoteCommunicationClient::MakeDirectory(const FileSpec &file_spec, if (response.GetChar() != 'F') return Status("invalid response to '%s' packet", packet.str().c_str()); - return Status(response.GetU32(UINT32_MAX), eErrorTypePOSIX); + return Status(response.GetHexMaxU32(false, UINT32_MAX), eErrorTypePOSIX); } Status @@ -2980,7 +2980,18 @@ GDBRemoteCommunicationClient::SetFilePermissions(const FileSpec &file_spec, if (response.GetChar() != 'F') return Status("invalid response to '%s' packet", stream.GetData()); - return Status(response.GetU32(UINT32_MAX), eErrorTypePOSIX); + return Status(response.GetHexMaxU32(false, UINT32_MAX), eErrorTypePOSIX); +} + +static int gdb_errno_to_system(int err) { + switch (err) { +#define HANDLE_ERRNO(name, value) \ + case GDB_##name: \ + return name; +#include "Plugins/Process/gdb-remote/GDBRemoteErrno.def" + default: + return -1; + } } static uint64_t ParseHostIOPacketResponse(StringExtractorGDBRemote &response, @@ -2988,12 +2999,12 @@ static uint64_t ParseHostIOPacketResponse(StringExtractorGDBRemote &response, response.SetFilePos(0); if (response.GetChar() != 'F') return fail_result; - int32_t result = response.GetS32(-2); + int32_t result = response.GetS32(-2, 16); if (result == -2) return fail_result; if (response.GetChar() == ',') { - int result_errno = response.GetS32(-2); - if (result_errno != -2) + int result_errno = gdb_errno_to_system(response.GetS32(-1, 16)); + if (result_errno != -1) error.SetError(result_errno, eErrorTypePOSIX); else error.SetError(-1, eErrorTypeGeneric); @@ -3026,7 +3037,7 @@ GDBRemoteCommunicationClient::OpenFile(const lldb_private::FileSpec &file_spec, bool GDBRemoteCommunicationClient::CloseFile(lldb::user_id_t fd, Status &error) { lldb_private::StreamString stream; - stream.Printf("vFile:close:%i", (int)fd); + stream.Printf("vFile:close:%x", (int)fd); StringExtractorGDBRemote response; if (SendPacketAndWaitForResponse(stream.GetString(), response) == PacketResult::Success) { @@ -3035,22 +3046,66 @@ bool GDBRemoteCommunicationClient::CloseFile(lldb::user_id_t fd, return false; } -// Extension of host I/O packets to get the file size. -lldb::user_id_t GDBRemoteCommunicationClient::GetFileSize( - const lldb_private::FileSpec &file_spec) { - std::string path(file_spec.GetPath(false)); +llvm::Optional<GDBRemoteFStatData> +GDBRemoteCommunicationClient::FStat(lldb::user_id_t fd) { lldb_private::StreamString stream; - stream.PutCString("vFile:size:"); - stream.PutStringAsRawHex8(path); + stream.Printf("vFile:fstat:%" PRIx64, fd); StringExtractorGDBRemote response; if (SendPacketAndWaitForResponse(stream.GetString(), response) == PacketResult::Success) { if (response.GetChar() != 'F') + return llvm::None; + int64_t size = response.GetS64(-1, 16); + if (size > 0 && response.GetChar() == ';') { + std::string buffer; + if (response.GetEscapedBinaryData(buffer)) { + GDBRemoteFStatData out; + if (buffer.size() != sizeof(out)) + return llvm::None; + memcpy(&out, buffer.data(), sizeof(out)); + return out; + } + } + } + return llvm::None; +} + +llvm::Optional<GDBRemoteFStatData> +GDBRemoteCommunicationClient::Stat(const lldb_private::FileSpec &file_spec) { + Status error; + lldb::user_id_t fd = OpenFile(file_spec, File::eOpenOptionReadOnly, 0, error); + if (fd == UINT64_MAX) + return llvm::None; + llvm::Optional<GDBRemoteFStatData> st = FStat(fd); + CloseFile(fd, error); + return st; +} + +// Extension of host I/O packets to get the file size. +lldb::user_id_t GDBRemoteCommunicationClient::GetFileSize( + const lldb_private::FileSpec &file_spec) { + if (m_supports_vFileSize) { + std::string path(file_spec.GetPath(false)); + lldb_private::StreamString stream; + stream.PutCString("vFile:size:"); + stream.PutStringAsRawHex8(path); + StringExtractorGDBRemote response; + if (SendPacketAndWaitForResponse(stream.GetString(), response) != + PacketResult::Success) return UINT64_MAX; - uint32_t retcode = response.GetHexMaxU64(false, UINT64_MAX); - return retcode; + + if (!response.IsUnsupportedResponse()) { + if (response.GetChar() != 'F') + return UINT64_MAX; + uint32_t retcode = response.GetHexMaxU64(false, UINT64_MAX); + return retcode; + } + m_supports_vFileSize = false; } - return UINT64_MAX; + + // Fallback to fstat. + llvm::Optional<GDBRemoteFStatData> st = Stat(file_spec); + return st ? st->gdb_st_size : UINT64_MAX; } void GDBRemoteCommunicationClient::AutoCompleteDiskFileOrDirectory( @@ -3081,37 +3136,50 @@ void GDBRemoteCommunicationClient::AutoCompleteDiskFileOrDirectory( Status GDBRemoteCommunicationClient::GetFilePermissions(const FileSpec &file_spec, uint32_t &file_permissions) { - std::string path{file_spec.GetPath(false)}; - Status error; - lldb_private::StreamString stream; - stream.PutCString("vFile:mode:"); - stream.PutStringAsRawHex8(path); - StringExtractorGDBRemote response; - if (SendPacketAndWaitForResponse(stream.GetString(), response) == - PacketResult::Success) { - if (response.GetChar() != 'F') { - error.SetErrorStringWithFormat("invalid response to '%s' packet", + if (m_supports_vFileMode) { + std::string path{file_spec.GetPath(false)}; + Status error; + lldb_private::StreamString stream; + stream.PutCString("vFile:mode:"); + stream.PutStringAsRawHex8(path); + StringExtractorGDBRemote response; + if (SendPacketAndWaitForResponse(stream.GetString(), response) != + PacketResult::Success) { + error.SetErrorStringWithFormat("failed to send '%s' packet", stream.GetData()); - } else { - const uint32_t mode = response.GetS32(-1); - if (static_cast<int32_t>(mode) == -1) { - if (response.GetChar() == ',') { - int response_errno = response.GetS32(-1); - if (response_errno > 0) - error.SetError(response_errno, lldb::eErrorTypePOSIX); - else - error.SetErrorToGenericError(); - } else - error.SetErrorToGenericError(); + return error; + } + if (!response.IsUnsupportedResponse()) { + if (response.GetChar() != 'F') { + error.SetErrorStringWithFormat("invalid response to '%s' packet", + stream.GetData()); } else { - file_permissions = mode & (S_IRWXU | S_IRWXG | S_IRWXO); + const uint32_t mode = response.GetS32(-1, 16); + if (static_cast<int32_t>(mode) == -1) { + if (response.GetChar() == ',') { + int response_errno = gdb_errno_to_system(response.GetS32(-1, 16)); + if (response_errno > 0) + error.SetError(response_errno, lldb::eErrorTypePOSIX); + else + error.SetErrorToGenericError(); + } else + error.SetErrorToGenericError(); + } else { + file_permissions = mode & (S_IRWXU | S_IRWXG | S_IRWXO); + } } + return error; + } else { // response.IsUnsupportedResponse() + m_supports_vFileMode = false; } - } else { - error.SetErrorStringWithFormat("failed to send '%s' packet", - stream.GetData()); } - return error; + + // Fallback to fstat. + if (llvm::Optional<GDBRemoteFStatData> st = Stat(file_spec)) { + file_permissions = st->gdb_st_mode & (S_IRWXU | S_IRWXG | S_IRWXO); + return Status(); + } + return Status("fstat failed"); } uint64_t GDBRemoteCommunicationClient::ReadFile(lldb::user_id_t fd, @@ -3119,16 +3187,23 @@ uint64_t GDBRemoteCommunicationClient::ReadFile(lldb::user_id_t fd, uint64_t dst_len, Status &error) { lldb_private::StreamString stream; - stream.Printf("vFile:pread:%i,%" PRId64 ",%" PRId64, (int)fd, dst_len, + stream.Printf("vFile:pread:%x,%" PRIx64 ",%" PRIx64, (int)fd, dst_len, offset); StringExtractorGDBRemote response; if (SendPacketAndWaitForResponse(stream.GetString(), response) == PacketResult::Success) { if (response.GetChar() != 'F') return 0; - uint32_t retcode = response.GetHexMaxU32(false, UINT32_MAX); - if (retcode == UINT32_MAX) - return retcode; + int64_t retcode = response.GetS64(-1, 16); + if (retcode == -1) { + error.SetErrorToGenericError(); + if (response.GetChar() == ',') { + int response_errno = gdb_errno_to_system(response.GetS32(-1, 16)); + if (response_errno > 0) + error.SetError(response_errno, lldb::eErrorTypePOSIX); + } + return -1; + } const char next = (response.Peek() ? *response.Peek() : 0); if (next == ',') return 0; @@ -3153,7 +3228,7 @@ uint64_t GDBRemoteCommunicationClient::WriteFile(lldb::user_id_t fd, uint64_t src_len, Status &error) { lldb_private::StreamGDBRemote stream; - stream.Printf("vFile:pwrite:%i,%" PRId64 ",", (int)fd, offset); + stream.Printf("vFile:pwrite:%x,%" PRIx64 ",", (int)fd, offset); stream.PutEscapedBytes(src, src_len); StringExtractorGDBRemote response; if (SendPacketAndWaitForResponse(stream.GetString(), response) == @@ -3162,15 +3237,15 @@ uint64_t GDBRemoteCommunicationClient::WriteFile(lldb::user_id_t fd, error.SetErrorStringWithFormat("write file failed"); return 0; } - uint64_t bytes_written = response.GetU64(UINT64_MAX); - if (bytes_written == UINT64_MAX) { + int64_t bytes_written = response.GetS64(-1, 16); + if (bytes_written == -1) { error.SetErrorToGenericError(); if (response.GetChar() == ',') { - int response_errno = response.GetS32(-1); + int response_errno = gdb_errno_to_system(response.GetS32(-1, 16)); if (response_errno > 0) error.SetError(response_errno, lldb::eErrorTypePOSIX); } - return 0; + return -1; } return bytes_written; } else { @@ -3194,11 +3269,11 @@ Status GDBRemoteCommunicationClient::CreateSymlink(const FileSpec &src, if (SendPacketAndWaitForResponse(stream.GetString(), response) == PacketResult::Success) { if (response.GetChar() == 'F') { - uint32_t result = response.GetU32(UINT32_MAX); + uint32_t result = response.GetHexMaxU32(false, UINT32_MAX); if (result != 0) { error.SetErrorToGenericError(); if (response.GetChar() == ',') { - int response_errno = response.GetS32(-1); + int response_errno = gdb_errno_to_system(response.GetS32(-1, 16)); if (response_errno > 0) error.SetError(response_errno, lldb::eErrorTypePOSIX); } @@ -3225,11 +3300,11 @@ Status GDBRemoteCommunicationClient::Unlink(const FileSpec &file_spec) { if (SendPacketAndWaitForResponse(stream.GetString(), response) == PacketResult::Success) { if (response.GetChar() == 'F') { - uint32_t result = response.GetU32(UINT32_MAX); + uint32_t result = response.GetHexMaxU32(false, UINT32_MAX); if (result != 0) { error.SetErrorToGenericError(); if (response.GetChar() == ',') { - int response_errno = response.GetS32(-1); + int response_errno = gdb_errno_to_system(response.GetS32(-1, 16)); if (response_errno > 0) error.SetError(response_errno, lldb::eErrorTypePOSIX); } @@ -3247,21 +3322,33 @@ Status GDBRemoteCommunicationClient::Unlink(const FileSpec &file_spec) { // Extension of host I/O packets to get whether a file exists. bool GDBRemoteCommunicationClient::GetFileExists( const lldb_private::FileSpec &file_spec) { - std::string path(file_spec.GetPath(false)); - lldb_private::StreamString stream; - stream.PutCString("vFile:exists:"); - stream.PutStringAsRawHex8(path); - StringExtractorGDBRemote response; - if (SendPacketAndWaitForResponse(stream.GetString(), response) == - PacketResult::Success) { - if (response.GetChar() != 'F') - return false; - if (response.GetChar() != ',') + if (m_supports_vFileExists) { + std::string path(file_spec.GetPath(false)); + lldb_private::StreamString stream; + stream.PutCString("vFile:exists:"); + stream.PutStringAsRawHex8(path); + StringExtractorGDBRemote response; + if (SendPacketAndWaitForResponse(stream.GetString(), response) != + PacketResult::Success) return false; - bool retcode = (response.GetChar() != '0'); - return retcode; + if (!response.IsUnsupportedResponse()) { + if (response.GetChar() != 'F') + return false; + if (response.GetChar() != ',') + return false; + bool retcode = (response.GetChar() != '0'); + return retcode; + } else + m_supports_vFileExists = false; } - return false; + + // Fallback to open. + Status error; + lldb::user_id_t fd = OpenFile(file_spec, File::eOpenOptionReadOnly, 0, error); + if (fd == UINT64_MAX) + return false; + CloseFile(fd, error); + return true; } bool GDBRemoteCommunicationClient::CalculateMD5( @@ -3790,15 +3877,14 @@ GDBRemoteCommunicationClient::GetModulesInfo( // query the target remote for extended information using the qXfer packet // -// example: object='features', annex='target.xml', out=<xml output> return: -// 'true' on success -// 'false' on failure (err set) -bool GDBRemoteCommunicationClient::ReadExtFeature( - const lldb_private::ConstString object, - const lldb_private::ConstString annex, std::string &out, - lldb_private::Status &err) { - - std::stringstream output; +// example: object='features', annex='target.xml' +// return: <xml output> or error +llvm::Expected<std::string> +GDBRemoteCommunicationClient::ReadExtFeature(llvm::StringRef object, + llvm::StringRef annex) { + + std::string output; + llvm::raw_string_ostream output_stream(output); StringExtractorGDBRemote chunk; uint64_t size = GetRemoteMaxPacketSize(); @@ -3812,28 +3898,22 @@ bool GDBRemoteCommunicationClient::ReadExtFeature( while (active) { // send query extended feature packet - std::stringstream packet; - packet << "qXfer:" << object.AsCString("") - << ":read:" << annex.AsCString("") << ":" << std::hex << offset - << "," << std::hex << size; + std::string packet = + ("qXfer:" + object + ":read:" + annex + ":" + + llvm::Twine::utohexstr(offset) + "," + llvm::Twine::utohexstr(size)) + .str(); GDBRemoteCommunication::PacketResult res = - SendPacketAndWaitForResponse(packet.str(), chunk); + SendPacketAndWaitForResponse(packet, chunk); - if (res != GDBRemoteCommunication::PacketResult::Success) { - err.SetErrorString("Error sending $qXfer packet"); - return false; - } - - const std::string &str = std::string(chunk.GetStringRef()); - if (str.length() == 0) { - // should have some data in chunk - err.SetErrorString("Empty response from $qXfer packet"); - return false; + if (res != GDBRemoteCommunication::PacketResult::Success || + chunk.GetStringRef().empty()) { + return llvm::createStringError(llvm::inconvertibleErrorCode(), + "Error sending $qXfer packet"); } // check packet code - switch (str[0]) { + switch (chunk.GetStringRef()[0]) { // last chunk case ('l'): active = false; @@ -3841,21 +3921,19 @@ bool GDBRemoteCommunicationClient::ReadExtFeature( // more chunks case ('m'): - if (str.length() > 1) - output << &str[1]; - offset += str.length() - 1; + output_stream << chunk.GetStringRef().drop_front(); + offset += chunk.GetStringRef().size() - 1; break; // unknown chunk default: - err.SetErrorString("Invalid continuation code from $qXfer packet"); - return false; + return llvm::createStringError( + llvm::inconvertibleErrorCode(), + "Invalid continuation code from $qXfer packet"); } } - out = output.str(); - err.Success(); - return true; + return output_stream.str(); } // Notify the target that gdb is prepared to serve symbol lookup requests. @@ -4146,3 +4224,14 @@ void GDBRemoteCommunicationClient::OnRunPacketSent(bool first) { GDBRemoteClientBase::OnRunPacketSent(first); m_curr_tid = LLDB_INVALID_THREAD_ID; } + +bool GDBRemoteCommunicationClient::UsesNativeSignals() { + if (m_uses_native_signals == eLazyBoolCalculate) + GetRemoteQSupported(); + if (m_uses_native_signals == eLazyBoolYes) + return true; + + // If the remote didn't indicate native-signal support explicitly, + // check whether it is an old version of lldb-server. + return GetThreadSuffixSupported(); +} diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h b/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h index 1e1797c10dfc..6765372ce124 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h +++ b/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h @@ -65,27 +65,6 @@ public: // we are communicating with it. bool HandshakeWithServer(Status *error_ptr); - // For packets which specify a range of output to be returned, - // return all of the output via a series of request packets of the form - // <prefix>0,<size> - // <prefix><size>,<size> - // <prefix><size>*2,<size> - // <prefix><size>*3,<size> - // ... - // until a "$l..." packet is received, indicating the end. - // (size is in hex; this format is used by a standard gdbserver to - // return the given portion of the output specified by <prefix>; - // for example, "qXfer:libraries-svr4:read::fff,1000" means - // "return a chunk of the xml description file for shared - // library load addresses, where the chunk starts at offset 0xfff - // and continues for 0x1000 bytes"). - // Concatenate the resulting server response packets together and - // return in response_string. If any packet fails, the return value - // indicates that failure and the returned string value is undefined. - PacketResult - SendPacketsAndConcatenateResponses(const char *send_payload_prefix, - std::string &response_string); - bool GetThreadSuffixSupported(); // This packet is usually sent first and the boolean return value @@ -147,21 +126,6 @@ public: int SendLaunchEventDataPacket(const char *data, bool *was_supported = nullptr); - /// Sends a "vAttach:PID" where PID is in hex. - /// - /// \param[in] pid - /// A process ID for the remote gdb server to attach to. - /// - /// \param[out] response - /// The response received from the gdb server. If the return - /// value is zero, \a response will contain a stop reply - /// packet. - /// - /// \return - /// Zero if the attach was successful, or an error indicating - /// an error code. - int SendAttach(lldb::pid_t pid, StringExtractorGDBRemote &response); - /// Sends a GDB remote protocol 'I' packet that delivers stdin /// data to the remote process. /// @@ -235,7 +199,7 @@ public: bool DeallocateMemory(lldb::addr_t addr); - Status Detach(bool keep_stopped); + Status Detach(bool keep_stopped, lldb::pid_t pid = LLDB_INVALID_PROCESS_ID); Status GetMemoryRegionInfo(lldb::addr_t addr, MemoryRegionInfo &range_info); @@ -275,9 +239,9 @@ public: llvm::VersionTuple GetMacCatalystVersion(); - bool GetOSBuildString(std::string &s); + llvm::Optional<std::string> GetOSBuildString(); - bool GetOSKernelDescription(std::string &s); + llvm::Optional<std::string> GetOSKernelDescription(); ArchSpec GetSystemArchitecture(); @@ -330,8 +294,6 @@ public: uint32_t length, // Byte Size of breakpoint or watchpoint std::chrono::seconds interrupt_timeout); // Time to wait for an interrupt - bool SetNonStopMode(const bool enable); - void TestPacketSpeed(const uint32_t num_packets, uint32_t max_send, uint32_t max_recv, uint64_t recv_amount, bool json, Stream &strm); @@ -391,6 +353,12 @@ public: bool CloseFile(lldb::user_id_t fd, Status &error); + llvm::Optional<GDBRemoteFStatData> FStat(lldb::user_id_t fd); + + // NB: this is just a convenience wrapper over open() + fstat(). It does not + // work if the file cannot be opened. + llvm::Optional<GDBRemoteFStatData> Stat(const FileSpec &file_spec); + lldb::user_id_t GetFileSize(const FileSpec &file_spec); void AutoCompleteDiskFileOrDirectory(CompletionRequest &request, @@ -465,6 +433,8 @@ public: bool GetMemoryTaggingSupported(); + bool UsesNativeSignals(); + lldb::DataBufferSP ReadMemoryTags(lldb::addr_t addr, size_t len, int32_t type); @@ -483,9 +453,8 @@ public: GetModulesInfo(llvm::ArrayRef<FileSpec> module_file_specs, const llvm::Triple &triple); - bool ReadExtFeature(const lldb_private::ConstString object, - const lldb_private::ConstString annex, std::string &out, - lldb_private::Status &err); + llvm::Expected<std::string> ReadExtFeature(llvm::StringRef object, + llvm::StringRef annex); void ServeSymbolLookups(lldb_private::Process *process); @@ -547,6 +516,8 @@ public: SendTraceGetBinaryData(const TraceGetBinaryDataRequest &request, std::chrono::seconds interrupt_timeout); + bool GetSaveCoreSupported() const; + protected: LazyBool m_supports_not_sending_acks = eLazyBoolCalculate; LazyBool m_supports_thread_suffix = eLazyBoolCalculate; @@ -585,6 +556,8 @@ protected: LazyBool m_supports_error_string_reply = eLazyBoolCalculate; LazyBool m_supports_multiprocess = eLazyBoolCalculate; LazyBool m_supports_memory_tagging = eLazyBoolCalculate; + LazyBool m_supports_qSaveCore = eLazyBoolCalculate; + LazyBool m_uses_native_signals = eLazyBoolCalculate; bool m_supports_qProcessInfoPID : 1, m_supports_qfProcessInfo : 1, m_supports_qUserName : 1, m_supports_qGroupName : 1, @@ -593,7 +566,9 @@ protected: m_supports_QEnvironment : 1, m_supports_QEnvironmentHexEncoded : 1, m_supports_qSymbol : 1, m_qSymbol_requests_done : 1, m_supports_qModuleInfo : 1, m_supports_jThreadsInfo : 1, - m_supports_jModulesInfo : 1; + m_supports_jModulesInfo : 1, m_supports_vFileSize : 1, + m_supports_vFileMode : 1, m_supports_vFileExists : 1, + m_supports_vRun : 1; /// Current gdb remote protocol process identifier for all other operations lldb::pid_t m_curr_pid = LLDB_INVALID_PROCESS_ID; diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp index b2b802552720..f371649842e8 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp @@ -157,6 +157,9 @@ GDBRemoteCommunicationServerCommon::GDBRemoteCommunicationServerCommon( StringExtractorGDBRemote::eServerPacketType_vFile_size, &GDBRemoteCommunicationServerCommon::Handle_vFile_Size); RegisterMemberFunctionHandler( + StringExtractorGDBRemote::eServerPacketType_vFile_fstat, + &GDBRemoteCommunicationServerCommon::Handle_vFile_FStat); + RegisterMemberFunctionHandler( StringExtractorGDBRemote::eServerPacketType_vFile_stat, &GDBRemoteCommunicationServerCommon::Handle_vFile_Stat); RegisterMemberFunctionHandler( @@ -264,18 +267,18 @@ GDBRemoteCommunicationServerCommon::Handle_qHostInfo( } #endif - std::string s; - if (HostInfo::GetOSBuildString(s)) { + if (llvm::Optional<std::string> s = HostInfo::GetOSBuildString()) { response.PutCString("os_build:"); - response.PutStringAsRawHex8(s); + response.PutStringAsRawHex8(*s); response.PutChar(';'); } - if (HostInfo::GetOSKernelDescription(s)) { + if (llvm::Optional<std::string> s = HostInfo::GetOSKernelDescription()) { response.PutCString("os_kernel:"); - response.PutStringAsRawHex8(s); + response.PutStringAsRawHex8(*s); response.PutChar(';'); } + std::string s; #if defined(__APPLE__) #if defined(__arm__) || defined(__arm64__) || defined(__aarch64__) @@ -501,10 +504,6 @@ GDBRemoteCommunicationServerCommon::Handle_vFile_Open( packet.GetHexByteStringTerminatedBy(path, ','); if (!path.empty()) { if (packet.GetChar() == ',') { - // FIXME - // The flag values for OpenOptions do not match the values used by GDB - // * https://sourceware.org/gdb/onlinedocs/gdb/Open-Flags.html#Open-Flags - // * rdar://problem/46788934 auto flags = File::OpenOptions(packet.GetHexMaxU32(false, 0)); if (packet.GetChar() == ',') { mode_t mode = packet.GetHexMaxU32(false, 0600); @@ -513,22 +512,21 @@ GDBRemoteCommunicationServerCommon::Handle_vFile_Open( // Do not close fd. auto file = FileSystem::Instance().Open(path_spec, flags, mode, false); - int save_errno = 0; + StreamString response; + response.PutChar('F'); + int descriptor = File::kInvalidDescriptor; if (file) { descriptor = file.get()->GetDescriptor(); + response.Printf("%x", descriptor); } else { + response.PutCString("-1"); std::error_code code = errorToErrorCode(file.takeError()); if (code.category() == std::system_category()) { - save_errno = code.value(); + response.Printf(",%x", code.value()); } } - StreamString response; - response.PutChar('F'); - response.Printf("%i", descriptor); - if (save_errno) - response.Printf(",%i", save_errno); return SendPacketNoLock(response.GetString()); } } @@ -536,11 +534,22 @@ GDBRemoteCommunicationServerCommon::Handle_vFile_Open( return SendErrorResponse(18); } +static GDBErrno system_errno_to_gdb(int err) { + switch (err) { +#define HANDLE_ERRNO(name, value) \ + case name: \ + return GDB_##name; +#include "Plugins/Process/gdb-remote/GDBRemoteErrno.def" + default: + return GDB_EUNKNOWN; + } +} + GDBRemoteCommunication::PacketResult GDBRemoteCommunicationServerCommon::Handle_vFile_Close( StringExtractorGDBRemote &packet) { packet.SetFilePos(::strlen("vFile:close:")); - int fd = packet.GetS32(-1); + int fd = packet.GetS32(-1, 16); int err = -1; int save_errno = 0; if (fd >= 0) { @@ -553,9 +562,9 @@ GDBRemoteCommunicationServerCommon::Handle_vFile_Close( } StreamString response; response.PutChar('F'); - response.Printf("%i", err); + response.Printf("%x", err); if (save_errno) - response.Printf(",%i", save_errno); + response.Printf(",%x", system_errno_to_gdb(save_errno)); return SendPacketNoLock(response.GetString()); } @@ -564,28 +573,29 @@ GDBRemoteCommunicationServerCommon::Handle_vFile_pRead( StringExtractorGDBRemote &packet) { StreamGDBRemote response; packet.SetFilePos(::strlen("vFile:pread:")); - int fd = packet.GetS32(-1); + int fd = packet.GetS32(-1, 16); if (packet.GetChar() == ',') { - size_t count = packet.GetU64(SIZE_MAX); + size_t count = packet.GetHexMaxU64(false, SIZE_MAX); if (packet.GetChar() == ',') { - off_t offset = packet.GetU64(UINT32_MAX); + off_t offset = packet.GetHexMaxU32(false, UINT32_MAX); if (count == SIZE_MAX) { - response.Printf("F-1:%i", EINVAL); + response.Printf("F-1:%x", EINVAL); return SendPacketNoLock(response.GetString()); } std::string buffer(count, 0); - NativeFile file(fd, File::eOpenOptionRead, false); + NativeFile file(fd, File::eOpenOptionReadOnly, false); Status error = file.Read(static_cast<void *>(&buffer[0]), count, offset); - const ssize_t bytes_read = error.Success() ? count : -1; const int save_errno = error.GetError(); response.PutChar('F'); - response.Printf("%zi", bytes_read); - if (save_errno) - response.Printf(",%i", save_errno); - else { + if (error.Success()) { + response.Printf("%zx", count); response.PutChar(';'); - response.PutEscapedBytes(&buffer[0], bytes_read); + response.PutEscapedBytes(&buffer[0], count); + } else { + response.PutCString("-1"); + if (save_errno) + response.Printf(",%x", system_errno_to_gdb(save_errno)); } return SendPacketNoLock(response.GetString()); } @@ -601,23 +611,26 @@ GDBRemoteCommunicationServerCommon::Handle_vFile_pWrite( StreamGDBRemote response; response.PutChar('F'); - int fd = packet.GetU32(UINT32_MAX); + int fd = packet.GetS32(-1, 16); if (packet.GetChar() == ',') { - off_t offset = packet.GetU64(UINT32_MAX); + off_t offset = packet.GetHexMaxU32(false, UINT32_MAX); if (packet.GetChar() == ',') { std::string buffer; if (packet.GetEscapedBinaryData(buffer)) { - NativeFile file(fd, File::eOpenOptionWrite, false); + NativeFile file(fd, File::eOpenOptionWriteOnly, false); size_t count = buffer.size(); Status error = file.Write(static_cast<const void *>(&buffer[0]), count, offset); - const ssize_t bytes_written = error.Success() ? count : -1; const int save_errno = error.GetError(); - response.Printf("%zi", bytes_written); - if (save_errno) - response.Printf(",%i", save_errno); + if (error.Success()) + response.Printf("%zx", count); + else { + response.PutCString("-1"); + if (save_errno) + response.Printf(",%x", system_errno_to_gdb(save_errno)); + } } else { - response.Printf("-1,%i", EINVAL); + response.Printf("-1,%x", EINVAL); } return SendPacketNoLock(response.GetString()); } @@ -659,9 +672,10 @@ GDBRemoteCommunicationServerCommon::Handle_vFile_Mode( std::error_code ec; const uint32_t mode = FileSystem::Instance().GetPermissions(file_spec, ec); StreamString response; - response.Printf("F%u", mode); - if (mode == 0 || ec) - response.Printf(",%i", (int)Status(ec).GetError()); + if (mode != llvm::sys::fs::perms_not_known) + response.Printf("F%x", mode); + else + response.Printf("F-1,%x", (int)Status(ec).GetError()); return SendPacketNoLock(response.GetString()); } return SendErrorResponse(23); @@ -701,7 +715,7 @@ GDBRemoteCommunicationServerCommon::Handle_vFile_symlink( Status error = FileSystem::Instance().Symlink(src_spec, FileSpec(dst)); StreamString response; - response.Printf("F%u,%u", error.GetError(), error.GetError()); + response.Printf("F%x,%x", error.GetError(), error.GetError()); return SendPacketNoLock(response.GetString()); } @@ -713,7 +727,7 @@ GDBRemoteCommunicationServerCommon::Handle_vFile_unlink( packet.GetHexByteString(path); Status error(llvm::sys::fs::remove(path)); StreamString response; - response.Printf("F%u,%u", error.GetError(), error.GetError()); + response.Printf("F%x,%x", error.GetError(), error.GetError()); return SendPacketNoLock(response.GetString()); } @@ -755,6 +769,54 @@ GDBRemoteCommunicationServerCommon::Handle_qPlatform_shell( return SendErrorResponse(24); } +template <typename T, typename U> +static void fill_clamp(T &dest, U src, typename T::value_type fallback) { + static_assert(std::is_unsigned<typename T::value_type>::value, + "Destination type must be unsigned."); + using UU = typename std::make_unsigned<U>::type; + constexpr auto T_max = std::numeric_limits<typename T::value_type>::max(); + dest = src >= 0 && static_cast<UU>(src) <= T_max ? src : fallback; +} + +GDBRemoteCommunication::PacketResult +GDBRemoteCommunicationServerCommon::Handle_vFile_FStat( + StringExtractorGDBRemote &packet) { + StreamGDBRemote response; + packet.SetFilePos(::strlen("vFile:fstat:")); + int fd = packet.GetS32(-1, 16); + + struct stat file_stats; + if (::fstat(fd, &file_stats) == -1) { + const int save_errno = errno; + response.Printf("F-1,%x", system_errno_to_gdb(save_errno)); + return SendPacketNoLock(response.GetString()); + } + + GDBRemoteFStatData data; + fill_clamp(data.gdb_st_dev, file_stats.st_dev, 0); + fill_clamp(data.gdb_st_ino, file_stats.st_ino, 0); + data.gdb_st_mode = file_stats.st_mode; + fill_clamp(data.gdb_st_nlink, file_stats.st_nlink, UINT32_MAX); + fill_clamp(data.gdb_st_uid, file_stats.st_uid, 0); + fill_clamp(data.gdb_st_gid, file_stats.st_gid, 0); + fill_clamp(data.gdb_st_rdev, file_stats.st_rdev, 0); + data.gdb_st_size = file_stats.st_size; +#if !defined(_WIN32) + data.gdb_st_blksize = file_stats.st_blksize; + data.gdb_st_blocks = file_stats.st_blocks; +#else + data.gdb_st_blksize = 0; + data.gdb_st_blocks = 0; +#endif + fill_clamp(data.gdb_st_atime, file_stats.st_atime, 0); + fill_clamp(data.gdb_st_mtime, file_stats.st_mtime, 0); + fill_clamp(data.gdb_st_ctime, file_stats.st_ctime, 0); + + response.Printf("F%zx;", sizeof(data)); + response.PutEscapedBytes(&data, sizeof(data)); + return SendPacketNoLock(response.GetString()); +} + GDBRemoteCommunication::PacketResult GDBRemoteCommunicationServerCommon::Handle_vFile_Stat( StringExtractorGDBRemote &packet) { @@ -795,7 +857,7 @@ GDBRemoteCommunicationServerCommon::Handle_qPlatform_mkdir( Status error(llvm::sys::fs::create_directory(path, mode)); StreamGDBRemote response; - response.Printf("F%u", error.GetError()); + response.Printf("F%x", error.GetError()); return SendPacketNoLock(response.GetString()); } @@ -815,7 +877,7 @@ GDBRemoteCommunicationServerCommon::Handle_qPlatform_chmod( Status error(llvm::sys::fs::setPermissions(path, perms)); StreamGDBRemote response; - response.Printf("F%u", error.GetError()); + response.Printf("F%x", error.GetError()); return SendPacketNoLock(response.GetString()); } @@ -1287,5 +1349,6 @@ std::vector<std::string> GDBRemoteCommunicationServerCommon::HandleFeatures( llvm::formatv("PacketSize={0}", max_packet_size), "QStartNoAckMode+", "qEcho+", + "native-signals+", }; } diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.h b/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.h index ecd80923fcf0..029972348ef0 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.h +++ b/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.h @@ -71,6 +71,8 @@ protected: PacketResult Handle_vFile_unlink(StringExtractorGDBRemote &packet); + PacketResult Handle_vFile_FStat(StringExtractorGDBRemote &packet); + PacketResult Handle_vFile_Stat(StringExtractorGDBRemote &packet); PacketResult Handle_vFile_MD5(StringExtractorGDBRemote &packet); diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp index 8e1f6bc29a6f..5360db3d8462 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp @@ -25,6 +25,7 @@ #include "lldb/Host/Host.h" #include "lldb/Host/HostInfo.h" #include "lldb/Host/PosixApi.h" +#include "lldb/Host/Socket.h" #include "lldb/Host/common/NativeProcessProtocol.h" #include "lldb/Host/common/NativeRegisterContext.h" #include "lldb/Host/common/NativeThreadProtocol.h" @@ -183,6 +184,9 @@ void GDBRemoteCommunicationServerLLGS::RegisterPacketHandlers() { StringExtractorGDBRemote::eServerPacketType_vCont_actions, &GDBRemoteCommunicationServerLLGS::Handle_vCont_actions); RegisterMemberFunctionHandler( + StringExtractorGDBRemote::eServerPacketType_vRun, + &GDBRemoteCommunicationServerLLGS::Handle_vRun); + RegisterMemberFunctionHandler( StringExtractorGDBRemote::eServerPacketType_x, &GDBRemoteCommunicationServerLLGS::Handle_memory_read); RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_Z, @@ -226,6 +230,10 @@ void GDBRemoteCommunicationServerLLGS::RegisterPacketHandlers() { quit = true; return this->Handle_k(packet); }); + + RegisterMemberFunctionHandler( + StringExtractorGDBRemote::eServerPacketType_qLLDBSaveCore, + &GDBRemoteCommunicationServerLLGS::Handle_qSaveCore); } void GDBRemoteCommunicationServerLLGS::SetLaunchInfo(const ProcessLaunchInfo &info) { @@ -278,7 +286,7 @@ Status GDBRemoteCommunicationServerLLGS::LaunchProcess() { if (should_forward_stdio) { // nullptr means it's not redirected to file or pty (in case of LLGS local) // at least one of stdio will be transferred pty<->gdb-remote we need to - // give the pty master handle to this object to read and/or write + // give the pty primary handle to this object to read and/or write LLDB_LOG(log, "pid = {0}: setting up stdout/stderr redirection via $O " "gdb-remote commands", @@ -331,7 +339,7 @@ Status GDBRemoteCommunicationServerLLGS::AttachToProcess(lldb::pid_t pid) { auto process_or = m_process_factory.Attach(pid, *this, m_mainloop); if (!process_or) { Status status(process_or.takeError()); - llvm::errs() << llvm::formatv("failed to attach to process {0}: {1}", pid, + llvm::errs() << llvm::formatv("failed to attach to process {0}: {1}\n", pid, status); return status; } @@ -1820,13 +1828,6 @@ GDBRemoteCommunicationServerLLGS::Handle_qRegisterInfo( response.PutChar(';'); } - if (reg_info->dynamic_size_dwarf_expr_bytes) { - const size_t dwarf_opcode_len = reg_info->dynamic_size_dwarf_len; - response.PutCString("dynamic_size_dwarf_expr_bytes:"); - for (uint32_t i = 0; i < dwarf_opcode_len; ++i) - response.PutHex8(reg_info->dynamic_size_dwarf_expr_bytes[i]); - response.PutChar(';'); - } return SendPacketNoLock(response.GetString()); } @@ -2064,12 +2065,8 @@ GDBRemoteCommunicationServerLLGS::Handle_P(StringExtractorGDBRemote &packet) { return SendErrorResponse(0x47); } - // The dwarf expression are evaluate on host site which may cause register - // size to change Hence the reg_size may not be same as reg_info->bytes_size - if ((reg_size != reg_info->byte_size) && - !(reg_info->dynamic_size_dwarf_expr_bytes)) { + if (reg_size != reg_info->byte_size) return SendIllFormedResponse(packet, "P packet register size is incorrect"); - } // Build the reginfos response. StreamGDBRemote response; @@ -2909,14 +2906,6 @@ GDBRemoteCommunicationServerLLGS::BuildTargetXml() { response.Printf("\" "); } - if (reg_info->dynamic_size_dwarf_expr_bytes) { - const size_t dwarf_opcode_len = reg_info->dynamic_size_dwarf_len; - response.PutCString("dynamic_size_dwarf_expr_bytes=\""); - for (uint32_t i = 0; i < dwarf_opcode_len; ++i) - response.PutHex8(reg_info->dynamic_size_dwarf_expr_bytes[i]); - response.Printf("\" "); - } - response.Printf("/>"); } @@ -3252,6 +3241,38 @@ GDBRemoteCommunicationServerLLGS::Handle_vAttachOrWait( } GDBRemoteCommunication::PacketResult +GDBRemoteCommunicationServerLLGS::Handle_vRun( + StringExtractorGDBRemote &packet) { + Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS)); + + llvm::StringRef s = packet.GetStringRef(); + if (!s.consume_front("vRun;")) + return SendErrorResponse(8); + + llvm::SmallVector<llvm::StringRef, 16> argv; + s.split(argv, ';'); + + for (llvm::StringRef hex_arg : argv) { + StringExtractor arg_ext{hex_arg}; + std::string arg; + arg_ext.GetHexByteString(arg); + m_process_launch_info.GetArguments().AppendArgument(arg); + LLDB_LOGF(log, "LLGSPacketHandler::%s added arg: \"%s\"", __FUNCTION__, + arg.c_str()); + } + + if (!argv.empty()) { + m_process_launch_info.GetExecutableFile().SetFile( + m_process_launch_info.GetArguments()[0].ref(), FileSpec::Style::native); + m_process_launch_error = LaunchProcess(); + if (m_process_launch_error.Success()) + return SendStopReasonForState(m_current_process->GetState()); + LLDB_LOG(log, "failed to launch exe: {0}", m_process_launch_error); + } + return SendErrorResponse(8); +} + +GDBRemoteCommunication::PacketResult GDBRemoteCommunicationServerLLGS::Handle_D(StringExtractorGDBRemote &packet) { StopSTDIOForwarding(); @@ -3604,6 +3625,37 @@ GDBRemoteCommunicationServerLLGS::Handle_QMemTags( return status.Success() ? SendOKResponse() : SendErrorResponse(1); } +GDBRemoteCommunication::PacketResult +GDBRemoteCommunicationServerLLGS::Handle_qSaveCore( + StringExtractorGDBRemote &packet) { + // Fail if we don't have a current process. + if (!m_current_process || + (m_current_process->GetID() == LLDB_INVALID_PROCESS_ID)) + return SendErrorResponse(Status("Process not running.")); + + std::string path_hint; + + StringRef packet_str{packet.GetStringRef()}; + assert(packet_str.startswith("qSaveCore")); + if (packet_str.consume_front("qSaveCore;")) { + for (auto x : llvm::split(packet_str, ';')) { + if (x.consume_front("path-hint:")) + StringExtractor(x).GetHexByteString(path_hint); + else + return SendErrorResponse(Status("Unsupported qSaveCore option")); + } + } + + llvm::Expected<std::string> ret = m_current_process->SaveCore(path_hint); + if (!ret) + return SendErrorResponse(ret.takeError()); + + StreamString response; + response.PutCString("core-path:"); + response.PutStringAsRawHex8(ret.get()); + return SendPacketNoLock(response.GetString()); +} + void GDBRemoteCommunicationServerLLGS::MaybeCloseInferiorTerminalConnection() { Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS)); @@ -3800,6 +3852,8 @@ std::vector<std::string> GDBRemoteCommunicationServerLLGS::HandleFeatures( ret.push_back("qXfer:libraries-svr4:read+"); if (bool(plugin_features & Extension::memory_tagging)) ret.push_back("memory-tagging+"); + if (bool(plugin_features & Extension::savecore)) + ret.push_back("qSaveCore+"); // check for client features m_extensions_supported = {}; @@ -3836,3 +3890,38 @@ void GDBRemoteCommunicationServerLLGS::SetEnabledExtensions( assert(!bool(flags & ~m_process_factory.GetSupportedExtensions())); process.SetEnabledExtensions(flags); } + +std::string +lldb_private::process_gdb_remote::LLGSArgToURL(llvm::StringRef url_arg, + bool reverse_connect) { + // Try parsing the argument as URL. + if (llvm::Optional<URI> url = URI::Parse(url_arg)) { + if (reverse_connect) + return url_arg.str(); + + // Translate the scheme from LLGS notation to ConnectionFileDescriptor. + // If the scheme doesn't match any, pass it through to support using CFD + // schemes directly. + std::string new_url = llvm::StringSwitch<std::string>(url->scheme) + .Case("tcp", "listen") + .Case("unix", "unix-accept") + .Case("unix-abstract", "unix-abstract-accept") + .Default(url->scheme.str()); + llvm::append_range(new_url, url_arg.substr(url->scheme.size())); + return new_url; + } + + std::string host_port = url_arg.str(); + // If host_and_port starts with ':', default the host to be "localhost" and + // expect the remainder to be the port. + if (url_arg.startswith(":")) + host_port.insert(0, "localhost"); + + // Try parsing the (preprocessed) argument as host:port pair. + if (!llvm::errorToBool(Socket::DecodeHostAndPort(host_port).takeError())) + return (reverse_connect ? "connect://" : "listen://") + host_port; + + // If none of the above applied, interpret the argument as UNIX socket path. + return (reverse_connect ? "unix-connect://" : "unix-accept://") + + url_arg.str(); +} diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h b/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h index 04d0605fe420..6c75771f6427 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h +++ b/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h @@ -202,6 +202,8 @@ protected: PacketResult Handle_vAttachOrWait(StringExtractorGDBRemote &packet); + PacketResult Handle_vRun(StringExtractorGDBRemote &packet); + PacketResult Handle_D(StringExtractorGDBRemote &packet); PacketResult Handle_qThreadStopInfo(StringExtractorGDBRemote &packet); @@ -214,6 +216,8 @@ protected: PacketResult Handle_QPassSignals(StringExtractorGDBRemote &packet); + PacketResult Handle_qSaveCore(StringExtractorGDBRemote &packet); + PacketResult Handle_g(StringExtractorGDBRemote &packet); PacketResult Handle_qMemTags(StringExtractorGDBRemote &packet); @@ -285,6 +289,8 @@ private: operator=(const GDBRemoteCommunicationServerLLGS &) = delete; }; +std::string LLGSArgToURL(llvm::StringRef url_arg, bool reverse_connect); + } // namespace process_gdb_remote } // namespace lldb_private diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.cpp index 7c2f80dc76b8..a63b98edec55 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.cpp @@ -197,16 +197,9 @@ Status GDBRemoteCommunicationServerPlatform::LaunchGDBServer( #endif uint16_t *port_ptr = port.getPointer(); if (m_socket_protocol == Socket::ProtocolTcp) { - llvm::StringRef platform_scheme; - llvm::StringRef platform_ip; - int platform_port; - llvm::StringRef platform_path; std::string platform_uri = GetConnection()->GetURI(); - bool ok = UriParser::Parse(platform_uri, platform_scheme, platform_ip, - platform_port, platform_path); - UNUSED_IF_ASSERT_DISABLED(ok); - assert(ok); - url << '[' << platform_ip.str() << "]:" << *port; + llvm::Optional<URI> parsed_uri = URI::Parse(platform_uri); + url << '[' << parsed_uri->hostname.str() << "]:" << *port; } else { socket_name = GetDomainSocketPath("gdbserver").GetPath(); url << socket_name; diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteErrno.def b/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteErrno.def new file mode 100644 index 000000000000..e26d23fdad0c --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteErrno.def @@ -0,0 +1,39 @@ +//===-- GDBRemoteErrno.def --------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// NOTE: NO INCLUDE GUARD DESIRED! + +// HANDLE_ERRNO(name, value) +#ifndef HANDLE_ERRNO +#error "HANDLE_ERRNO must be defined" +#endif + +// from gdb's include/gdb/fileio.h +HANDLE_ERRNO(EPERM, 1) +HANDLE_ERRNO(ENOENT, 2) +HANDLE_ERRNO(EINTR, 4) +HANDLE_ERRNO(EIO, 5) +HANDLE_ERRNO(EBADF, 9) +HANDLE_ERRNO(EACCES, 13) +HANDLE_ERRNO(EFAULT, 14) +HANDLE_ERRNO(EBUSY, 16) +HANDLE_ERRNO(EEXIST, 17) +HANDLE_ERRNO(ENODEV, 19) +HANDLE_ERRNO(ENOTDIR, 20) +HANDLE_ERRNO(EISDIR, 21) +HANDLE_ERRNO(EINVAL, 22) +HANDLE_ERRNO(ENFILE, 23) +HANDLE_ERRNO(EMFILE, 24) +HANDLE_ERRNO(EFBIG, 27) +HANDLE_ERRNO(ENOSPC, 28) +HANDLE_ERRNO(ESPIPE, 29) +HANDLE_ERRNO(EROFS, 30) +HANDLE_ERRNO(ENOSYS, 88) +HANDLE_ERRNO(ENAMETOOLONG, 91) + +#undef HANDLE_ERRNO diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp index 65cf9fb2a834..9410c9bd83ec 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp @@ -69,14 +69,7 @@ size_t GDBRemoteRegisterContext::GetRegisterCount() { const RegisterInfo * GDBRemoteRegisterContext::GetRegisterInfoAtIndex(size_t reg) { - RegisterInfo *reg_info = m_reg_info_sp->GetRegisterInfoAtIndex(reg); - - if (reg_info && reg_info->dynamic_size_dwarf_expr_bytes) { - const ArchSpec &arch = m_thread.GetProcess()->GetTarget().GetArchitecture(); - uint8_t reg_size = UpdateDynamicRegisterSize(arch, reg_info); - reg_info->byte_size = reg_size; - } - return reg_info; + return m_reg_info_sp->GetRegisterInfoAtIndex(reg); } size_t GDBRemoteRegisterContext::GetRegisterSetCount() { @@ -90,14 +83,38 @@ const RegisterSet *GDBRemoteRegisterContext::GetRegisterSet(size_t reg_set) { bool GDBRemoteRegisterContext::ReadRegister(const RegisterInfo *reg_info, RegisterValue &value) { // Read the register - if (ReadRegisterBytes(reg_info, m_reg_data)) { + if (ReadRegisterBytes(reg_info)) { const uint32_t reg = reg_info->kinds[eRegisterKindLLDB]; if (m_reg_valid[reg] == false) return false; - const bool partial_data_ok = false; - Status error(value.SetValueFromData( - reg_info, m_reg_data, reg_info->byte_offset, partial_data_ok)); - return error.Success(); + if (reg_info->value_regs && + reg_info->value_regs[0] != LLDB_INVALID_REGNUM && + reg_info->value_regs[1] != LLDB_INVALID_REGNUM) { + std::vector<char> combined_data; + uint32_t offset = 0; + for (int i = 0; reg_info->value_regs[i] != LLDB_INVALID_REGNUM; i++) { + const RegisterInfo *parent_reg = GetRegisterInfo( + eRegisterKindLLDB, reg_info->value_regs[i]); + if (!parent_reg) + return false; + combined_data.resize(offset + parent_reg->byte_size); + if (m_reg_data.CopyData(parent_reg->byte_offset, parent_reg->byte_size, + combined_data.data() + offset) != + parent_reg->byte_size) + return false; + offset += parent_reg->byte_size; + } + + Status error; + return value.SetFromMemoryData( + reg_info, combined_data.data(), combined_data.size(), + m_reg_data.GetByteOrder(), error) == combined_data.size(); + } else { + const bool partial_data_ok = false; + Status error(value.SetValueFromData( + reg_info, m_reg_data, reg_info->byte_offset, partial_data_ok)); + return error.Success(); + } } return false; } @@ -184,8 +201,7 @@ bool GDBRemoteRegisterContext::GetPrimordialRegister( return false; } -bool GDBRemoteRegisterContext::ReadRegisterBytes(const RegisterInfo *reg_info, - DataExtractor &data) { +bool GDBRemoteRegisterContext::ReadRegisterBytes(const RegisterInfo *reg_info) { ExecutionContext exe_ctx(CalculateThread()); Process *process = exe_ctx.GetProcessPtr(); @@ -211,16 +227,11 @@ bool GDBRemoteRegisterContext::ReadRegisterBytes(const RegisterInfo *reg_info, SetAllRegisterValid(true); return true; } else if (buffer_sp->GetByteSize() > 0) { - const int regcount = m_reg_info_sp->GetNumRegisters(); - for (int i = 0; i < regcount; i++) { - struct RegisterInfo *reginfo = - m_reg_info_sp->GetRegisterInfoAtIndex(i); - if (reginfo->byte_offset + reginfo->byte_size <= - buffer_sp->GetByteSize()) { - m_reg_valid[i] = true; - } else { - m_reg_valid[i] = false; - } + for (auto x : llvm::enumerate(m_reg_info_sp->registers())) { + const struct RegisterInfo ®info = x.value(); + m_reg_valid[x.index()] = + (reginfo.byte_offset + reginfo.byte_size <= + buffer_sp->GetByteSize()); } m_gpacket_cached = true; @@ -254,7 +265,7 @@ bool GDBRemoteRegisterContext::ReadRegisterBytes(const RegisterInfo *reg_info, // We have a valid primordial register as our constituent. Grab the // corresponding register info. const RegisterInfo *prim_reg_info = - GetRegisterInfo(eRegisterKindProcessPlugin, prim_reg); + GetRegisterInfo(eRegisterKindLLDB, prim_reg); if (prim_reg_info == nullptr) success = false; else { @@ -279,30 +290,44 @@ bool GDBRemoteRegisterContext::ReadRegisterBytes(const RegisterInfo *reg_info, return false; } - if (&data != &m_reg_data) { - assert(m_reg_data.GetByteSize() >= - reg_info->byte_offset + reg_info->byte_size); - // If our register context and our register info disagree, which should - // never happen, don't read past the end of the buffer. - if (m_reg_data.GetByteSize() < reg_info->byte_offset + reg_info->byte_size) - return false; - - // If we aren't extracting into our own buffer (which only happens when - // this function is called from ReadRegisterValue(uint32_t, Scalar&)) then - // we transfer bytes from our buffer into the data buffer that was passed - // in - - data.SetByteOrder(m_reg_data.GetByteOrder()); - data.SetData(m_reg_data, reg_info->byte_offset, reg_info->byte_size); - } return true; } bool GDBRemoteRegisterContext::WriteRegister(const RegisterInfo *reg_info, const RegisterValue &value) { DataExtractor data; - if (value.GetData(data)) - return WriteRegisterBytes(reg_info, data, 0); + if (value.GetData(data)) { + if (reg_info->value_regs && + reg_info->value_regs[0] != LLDB_INVALID_REGNUM && + reg_info->value_regs[1] != LLDB_INVALID_REGNUM) { + uint32_t combined_size = 0; + for (int i = 0; reg_info->value_regs[i] != LLDB_INVALID_REGNUM; i++) { + const RegisterInfo *parent_reg = GetRegisterInfo( + eRegisterKindLLDB, reg_info->value_regs[i]); + if (!parent_reg) + return false; + combined_size += parent_reg->byte_size; + } + + if (data.GetByteSize() < combined_size) + return false; + + uint32_t offset = 0; + for (int i = 0; reg_info->value_regs[i] != LLDB_INVALID_REGNUM; i++) { + const RegisterInfo *parent_reg = GetRegisterInfo( + eRegisterKindLLDB, reg_info->value_regs[i]); + assert(parent_reg); + + DataExtractor parent_data{data, offset, parent_reg->byte_size}; + if (!WriteRegisterBytes(parent_reg, parent_data, 0)) + return false; + offset += parent_reg->byte_size; + } + assert(offset == combined_size); + return true; + } else + return WriteRegisterBytes(reg_info, data, 0); + } return false; } @@ -401,7 +426,7 @@ bool GDBRemoteRegisterContext::WriteRegisterBytes(const RegisterInfo *reg_info, // We have a valid primordial register as our constituent. Grab the // corresponding register info. const RegisterInfo *value_reg_info = - GetRegisterInfo(eRegisterKindProcessPlugin, reg); + GetRegisterInfo(eRegisterKindLLDB, reg); if (value_reg_info == nullptr) success = false; else @@ -422,7 +447,7 @@ bool GDBRemoteRegisterContext::WriteRegisterBytes(const RegisterInfo *reg_info, reg != LLDB_INVALID_REGNUM; reg = reg_info->invalidate_regs[++idx]) SetRegisterIsValid(ConvertRegisterKindToRegisterNumber( - eRegisterKindProcessPlugin, reg), + eRegisterKindLLDB, reg), false); } @@ -526,7 +551,7 @@ bool GDBRemoteRegisterContext::ReadAllRegisterValues( if (reg_info ->value_regs) // skip registers that are slices of real registers continue; - ReadRegisterBytes(reg_info, m_reg_data); + ReadRegisterBytes(reg_info); // ReadRegisterBytes saves the contents of the register in to the // m_reg_data buffer } @@ -790,277 +815,3 @@ bool GDBRemoteDynamicRegisterInfo::UpdateARM64SVERegistersInfos(uint64_t vg) { ConfigureOffsets(); return true; } - -void GDBRemoteDynamicRegisterInfo::HardcodeARMRegisters(bool from_scratch) { - // For Advanced SIMD and VFP register mapping. - static uint32_t g_d0_regs[] = {26, 27, LLDB_INVALID_REGNUM}; // (s0, s1) - static uint32_t g_d1_regs[] = {28, 29, LLDB_INVALID_REGNUM}; // (s2, s3) - static uint32_t g_d2_regs[] = {30, 31, LLDB_INVALID_REGNUM}; // (s4, s5) - static uint32_t g_d3_regs[] = {32, 33, LLDB_INVALID_REGNUM}; // (s6, s7) - static uint32_t g_d4_regs[] = {34, 35, LLDB_INVALID_REGNUM}; // (s8, s9) - static uint32_t g_d5_regs[] = {36, 37, LLDB_INVALID_REGNUM}; // (s10, s11) - static uint32_t g_d6_regs[] = {38, 39, LLDB_INVALID_REGNUM}; // (s12, s13) - static uint32_t g_d7_regs[] = {40, 41, LLDB_INVALID_REGNUM}; // (s14, s15) - static uint32_t g_d8_regs[] = {42, 43, LLDB_INVALID_REGNUM}; // (s16, s17) - static uint32_t g_d9_regs[] = {44, 45, LLDB_INVALID_REGNUM}; // (s18, s19) - static uint32_t g_d10_regs[] = {46, 47, LLDB_INVALID_REGNUM}; // (s20, s21) - static uint32_t g_d11_regs[] = {48, 49, LLDB_INVALID_REGNUM}; // (s22, s23) - static uint32_t g_d12_regs[] = {50, 51, LLDB_INVALID_REGNUM}; // (s24, s25) - static uint32_t g_d13_regs[] = {52, 53, LLDB_INVALID_REGNUM}; // (s26, s27) - static uint32_t g_d14_regs[] = {54, 55, LLDB_INVALID_REGNUM}; // (s28, s29) - static uint32_t g_d15_regs[] = {56, 57, LLDB_INVALID_REGNUM}; // (s30, s31) - static uint32_t g_q0_regs[] = { - 26, 27, 28, 29, LLDB_INVALID_REGNUM}; // (d0, d1) -> (s0, s1, s2, s3) - static uint32_t g_q1_regs[] = { - 30, 31, 32, 33, LLDB_INVALID_REGNUM}; // (d2, d3) -> (s4, s5, s6, s7) - static uint32_t g_q2_regs[] = { - 34, 35, 36, 37, LLDB_INVALID_REGNUM}; // (d4, d5) -> (s8, s9, s10, s11) - static uint32_t g_q3_regs[] = { - 38, 39, 40, 41, LLDB_INVALID_REGNUM}; // (d6, d7) -> (s12, s13, s14, s15) - static uint32_t g_q4_regs[] = { - 42, 43, 44, 45, LLDB_INVALID_REGNUM}; // (d8, d9) -> (s16, s17, s18, s19) - static uint32_t g_q5_regs[] = { - 46, 47, 48, 49, - LLDB_INVALID_REGNUM}; // (d10, d11) -> (s20, s21, s22, s23) - static uint32_t g_q6_regs[] = { - 50, 51, 52, 53, - LLDB_INVALID_REGNUM}; // (d12, d13) -> (s24, s25, s26, s27) - static uint32_t g_q7_regs[] = { - 54, 55, 56, 57, - LLDB_INVALID_REGNUM}; // (d14, d15) -> (s28, s29, s30, s31) - static uint32_t g_q8_regs[] = {59, 60, LLDB_INVALID_REGNUM}; // (d16, d17) - static uint32_t g_q9_regs[] = {61, 62, LLDB_INVALID_REGNUM}; // (d18, d19) - static uint32_t g_q10_regs[] = {63, 64, LLDB_INVALID_REGNUM}; // (d20, d21) - static uint32_t g_q11_regs[] = {65, 66, LLDB_INVALID_REGNUM}; // (d22, d23) - static uint32_t g_q12_regs[] = {67, 68, LLDB_INVALID_REGNUM}; // (d24, d25) - static uint32_t g_q13_regs[] = {69, 70, LLDB_INVALID_REGNUM}; // (d26, d27) - static uint32_t g_q14_regs[] = {71, 72, LLDB_INVALID_REGNUM}; // (d28, d29) - static uint32_t g_q15_regs[] = {73, 74, LLDB_INVALID_REGNUM}; // (d30, d31) - - // This is our array of composite registers, with each element coming from - // the above register mappings. - static uint32_t *g_composites[] = { - g_d0_regs, g_d1_regs, g_d2_regs, g_d3_regs, g_d4_regs, g_d5_regs, - g_d6_regs, g_d7_regs, g_d8_regs, g_d9_regs, g_d10_regs, g_d11_regs, - g_d12_regs, g_d13_regs, g_d14_regs, g_d15_regs, g_q0_regs, g_q1_regs, - g_q2_regs, g_q3_regs, g_q4_regs, g_q5_regs, g_q6_regs, g_q7_regs, - g_q8_regs, g_q9_regs, g_q10_regs, g_q11_regs, g_q12_regs, g_q13_regs, - g_q14_regs, g_q15_regs}; - - // clang-format off - static RegisterInfo g_register_infos[] = { -// NAME ALT SZ OFF ENCODING FORMAT EH_FRAME DWARF GENERIC PROCESS PLUGIN LLDB VALUE REGS INVALIDATE REGS SIZE EXPR SIZE LEN -// ====== ====== === === ============= ========== =================== =================== ====================== ============= ==== ========== =============== ========= ======== - { "r0", "arg1", 4, 0, eEncodingUint, eFormatHex, { ehframe_r0, dwarf_r0, LLDB_REGNUM_GENERIC_ARG1,0, 0 }, nullptr, nullptr, nullptr, 0 }, - { "r1", "arg2", 4, 0, eEncodingUint, eFormatHex, { ehframe_r1, dwarf_r1, LLDB_REGNUM_GENERIC_ARG2,1, 1 }, nullptr, nullptr, nullptr, 0 }, - { "r2", "arg3", 4, 0, eEncodingUint, eFormatHex, { ehframe_r2, dwarf_r2, LLDB_REGNUM_GENERIC_ARG3,2, 2 }, nullptr, nullptr, nullptr, 0 }, - { "r3", "arg4", 4, 0, eEncodingUint, eFormatHex, { ehframe_r3, dwarf_r3, LLDB_REGNUM_GENERIC_ARG4,3, 3 }, nullptr, nullptr, nullptr, 0 }, - { "r4", nullptr, 4, 0, eEncodingUint, eFormatHex, { ehframe_r4, dwarf_r4, LLDB_INVALID_REGNUM, 4, 4 }, nullptr, nullptr, nullptr, 0 }, - { "r5", nullptr, 4, 0, eEncodingUint, eFormatHex, { ehframe_r5, dwarf_r5, LLDB_INVALID_REGNUM, 5, 5 }, nullptr, nullptr, nullptr, 0 }, - { "r6", nullptr, 4, 0, eEncodingUint, eFormatHex, { ehframe_r6, dwarf_r6, LLDB_INVALID_REGNUM, 6, 6 }, nullptr, nullptr, nullptr, 0 }, - { "r7", "fp", 4, 0, eEncodingUint, eFormatHex, { ehframe_r7, dwarf_r7, LLDB_REGNUM_GENERIC_FP, 7, 7 }, nullptr, nullptr, nullptr, 0 }, - { "r8", nullptr, 4, 0, eEncodingUint, eFormatHex, { ehframe_r8, dwarf_r8, LLDB_INVALID_REGNUM, 8, 8 }, nullptr, nullptr, nullptr, 0 }, - { "r9", nullptr, 4, 0, eEncodingUint, eFormatHex, { ehframe_r9, dwarf_r9, LLDB_INVALID_REGNUM, 9, 9 }, nullptr, nullptr, nullptr, 0 }, - { "r10", nullptr, 4, 0, eEncodingUint, eFormatHex, { ehframe_r10, dwarf_r10, LLDB_INVALID_REGNUM, 10, 10 }, nullptr, nullptr, nullptr, 0 }, - { "r11", nullptr, 4, 0, eEncodingUint, eFormatHex, { ehframe_r11, dwarf_r11, LLDB_INVALID_REGNUM, 11, 11 }, nullptr, nullptr, nullptr, 0 }, - { "r12", nullptr, 4, 0, eEncodingUint, eFormatHex, { ehframe_r12, dwarf_r12, LLDB_INVALID_REGNUM, 12, 12 }, nullptr, nullptr, nullptr, 0 }, - { "sp", "r13", 4, 0, eEncodingUint, eFormatHex, { ehframe_sp, dwarf_sp, LLDB_REGNUM_GENERIC_SP, 13, 13 }, nullptr, nullptr, nullptr, 0 }, - { "lr", "r14", 4, 0, eEncodingUint, eFormatHex, { ehframe_lr, dwarf_lr, LLDB_REGNUM_GENERIC_RA, 14, 14 }, nullptr, nullptr, nullptr, 0 }, - { "pc", "r15", 4, 0, eEncodingUint, eFormatHex, { ehframe_pc, dwarf_pc, LLDB_REGNUM_GENERIC_PC, 15, 15 }, nullptr, nullptr, nullptr, 0 }, - { "f0", nullptr, 12, 0, eEncodingUint, eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 16, 16 }, nullptr, nullptr, nullptr, 0 }, - { "f1", nullptr, 12, 0, eEncodingUint, eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 17, 17 }, nullptr, nullptr, nullptr, 0 }, - { "f2", nullptr, 12, 0, eEncodingUint, eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 18, 18 }, nullptr, nullptr, nullptr, 0 }, - { "f3", nullptr, 12, 0, eEncodingUint, eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 19, 19 }, nullptr, nullptr, nullptr, 0 }, - { "f4", nullptr, 12, 0, eEncodingUint, eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 20, 20 }, nullptr, nullptr, nullptr, 0 }, - { "f5", nullptr, 12, 0, eEncodingUint, eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 21, 21 }, nullptr, nullptr, nullptr, 0 }, - { "f6", nullptr, 12, 0, eEncodingUint, eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 22, 22 }, nullptr, nullptr, nullptr, 0 }, - { "f7", nullptr, 12, 0, eEncodingUint, eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 23, 23 }, nullptr, nullptr, nullptr, 0 }, - { "fps", nullptr, 4, 0, eEncodingUint, eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 24, 24 }, nullptr, nullptr, nullptr, 0 }, - { "cpsr","flags", 4, 0, eEncodingUint, eFormatHex, { ehframe_cpsr, dwarf_cpsr, LLDB_INVALID_REGNUM, 25, 25 }, nullptr, nullptr, nullptr, 0 }, - { "s0", nullptr, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s0, LLDB_INVALID_REGNUM, 26, 26 }, nullptr, nullptr, nullptr, 0 }, - { "s1", nullptr, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s1, LLDB_INVALID_REGNUM, 27, 27 }, nullptr, nullptr, nullptr, 0 }, - { "s2", nullptr, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s2, LLDB_INVALID_REGNUM, 28, 28 }, nullptr, nullptr, nullptr, 0 }, - { "s3", nullptr, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s3, LLDB_INVALID_REGNUM, 29, 29 }, nullptr, nullptr, nullptr, 0 }, - { "s4", nullptr, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s4, LLDB_INVALID_REGNUM, 30, 30 }, nullptr, nullptr, nullptr, 0 }, - { "s5", nullptr, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s5, LLDB_INVALID_REGNUM, 31, 31 }, nullptr, nullptr, nullptr, 0 }, - { "s6", nullptr, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s6, LLDB_INVALID_REGNUM, 32, 32 }, nullptr, nullptr, nullptr, 0 }, - { "s7", nullptr, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s7, LLDB_INVALID_REGNUM, 33, 33 }, nullptr, nullptr, nullptr, 0 }, - { "s8", nullptr, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s8, LLDB_INVALID_REGNUM, 34, 34 }, nullptr, nullptr, nullptr, 0 }, - { "s9", nullptr, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s9, LLDB_INVALID_REGNUM, 35, 35 }, nullptr, nullptr, nullptr, 0 }, - { "s10", nullptr, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s10, LLDB_INVALID_REGNUM, 36, 36 }, nullptr, nullptr, nullptr, 0 }, - { "s11", nullptr, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s11, LLDB_INVALID_REGNUM, 37, 37 }, nullptr, nullptr, nullptr, 0 }, - { "s12", nullptr, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s12, LLDB_INVALID_REGNUM, 38, 38 }, nullptr, nullptr, nullptr, 0 }, - { "s13", nullptr, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s13, LLDB_INVALID_REGNUM, 39, 39 }, nullptr, nullptr, nullptr, 0 }, - { "s14", nullptr, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s14, LLDB_INVALID_REGNUM, 40, 40 }, nullptr, nullptr, nullptr, 0 }, - { "s15", nullptr, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s15, LLDB_INVALID_REGNUM, 41, 41 }, nullptr, nullptr, nullptr, 0 }, - { "s16", nullptr, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s16, LLDB_INVALID_REGNUM, 42, 42 }, nullptr, nullptr, nullptr, 0 }, - { "s17", nullptr, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s17, LLDB_INVALID_REGNUM, 43, 43 }, nullptr, nullptr, nullptr, 0 }, - { "s18", nullptr, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s18, LLDB_INVALID_REGNUM, 44, 44 }, nullptr, nullptr, nullptr, 0 }, - { "s19", nullptr, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s19, LLDB_INVALID_REGNUM, 45, 45 }, nullptr, nullptr, nullptr, 0 }, - { "s20", nullptr, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s20, LLDB_INVALID_REGNUM, 46, 46 }, nullptr, nullptr, nullptr, 0 }, - { "s21", nullptr, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s21, LLDB_INVALID_REGNUM, 47, 47 }, nullptr, nullptr, nullptr, 0 }, - { "s22", nullptr, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s22, LLDB_INVALID_REGNUM, 48, 48 }, nullptr, nullptr, nullptr, 0 }, - { "s23", nullptr, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s23, LLDB_INVALID_REGNUM, 49, 49 }, nullptr, nullptr, nullptr, 0 }, - { "s24", nullptr, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s24, LLDB_INVALID_REGNUM, 50, 50 }, nullptr, nullptr, nullptr, 0 }, - { "s25", nullptr, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s25, LLDB_INVALID_REGNUM, 51, 51 }, nullptr, nullptr, nullptr, 0 }, - { "s26", nullptr, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s26, LLDB_INVALID_REGNUM, 52, 52 }, nullptr, nullptr, nullptr, 0 }, - { "s27", nullptr, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s27, LLDB_INVALID_REGNUM, 53, 53 }, nullptr, nullptr, nullptr, 0 }, - { "s28", nullptr, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s28, LLDB_INVALID_REGNUM, 54, 54 }, nullptr, nullptr, nullptr, 0 }, - { "s29", nullptr, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s29, LLDB_INVALID_REGNUM, 55, 55 }, nullptr, nullptr, nullptr, 0 }, - { "s30", nullptr, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s30, LLDB_INVALID_REGNUM, 56, 56 }, nullptr, nullptr, nullptr, 0 }, - { "s31", nullptr, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s31, LLDB_INVALID_REGNUM, 57, 57 }, nullptr, nullptr, nullptr, 0 }, - { "fpscr",nullptr, 4, 0, eEncodingUint, eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 58, 58 }, nullptr, nullptr, nullptr, 0 }, - { "d16", nullptr, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d16, LLDB_INVALID_REGNUM, 59, 59 }, nullptr, nullptr, nullptr, 0 }, - { "d17", nullptr, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d17, LLDB_INVALID_REGNUM, 60, 60 }, nullptr, nullptr, nullptr, 0 }, - { "d18", nullptr, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d18, LLDB_INVALID_REGNUM, 61, 61 }, nullptr, nullptr, nullptr, 0 }, - { "d19", nullptr, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d19, LLDB_INVALID_REGNUM, 62, 62 }, nullptr, nullptr, nullptr, 0 }, - { "d20", nullptr, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d20, LLDB_INVALID_REGNUM, 63, 63 }, nullptr, nullptr, nullptr, 0 }, - { "d21", nullptr, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d21, LLDB_INVALID_REGNUM, 64, 64 }, nullptr, nullptr, nullptr, 0 }, - { "d22", nullptr, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d22, LLDB_INVALID_REGNUM, 65, 65 }, nullptr, nullptr, nullptr, 0 }, - { "d23", nullptr, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d23, LLDB_INVALID_REGNUM, 66, 66 }, nullptr, nullptr, nullptr, 0 }, - { "d24", nullptr, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d24, LLDB_INVALID_REGNUM, 67, 67 }, nullptr, nullptr, nullptr, 0 }, - { "d25", nullptr, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d25, LLDB_INVALID_REGNUM, 68, 68 }, nullptr, nullptr, nullptr, 0 }, - { "d26", nullptr, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d26, LLDB_INVALID_REGNUM, 69, 69 }, nullptr, nullptr, nullptr, 0 }, - { "d27", nullptr, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d27, LLDB_INVALID_REGNUM, 70, 70 }, nullptr, nullptr, nullptr, 0 }, - { "d28", nullptr, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d28, LLDB_INVALID_REGNUM, 71, 71 }, nullptr, nullptr, nullptr, 0 }, - { "d29", nullptr, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d29, LLDB_INVALID_REGNUM, 72, 72 }, nullptr, nullptr, nullptr, 0 }, - { "d30", nullptr, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d30, LLDB_INVALID_REGNUM, 73, 73 }, nullptr, nullptr, nullptr, 0 }, - { "d31", nullptr, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d31, LLDB_INVALID_REGNUM, 74, 74 }, nullptr, nullptr, nullptr, 0 }, - { "d0", nullptr, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d0, LLDB_INVALID_REGNUM, 75, 75 }, g_d0_regs, nullptr, nullptr, 0 }, - { "d1", nullptr, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d1, LLDB_INVALID_REGNUM, 76, 76 }, g_d1_regs, nullptr, nullptr, 0 }, - { "d2", nullptr, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d2, LLDB_INVALID_REGNUM, 77, 77 }, g_d2_regs, nullptr, nullptr, 0 }, - { "d3", nullptr, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d3, LLDB_INVALID_REGNUM, 78, 78 }, g_d3_regs, nullptr, nullptr, 0 }, - { "d4", nullptr, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d4, LLDB_INVALID_REGNUM, 79, 79 }, g_d4_regs, nullptr, nullptr, 0 }, - { "d5", nullptr, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d5, LLDB_INVALID_REGNUM, 80, 80 }, g_d5_regs, nullptr, nullptr, 0 }, - { "d6", nullptr, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d6, LLDB_INVALID_REGNUM, 81, 81 }, g_d6_regs, nullptr, nullptr, 0 }, - { "d7", nullptr, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d7, LLDB_INVALID_REGNUM, 82, 82 }, g_d7_regs, nullptr, nullptr, 0 }, - { "d8", nullptr, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d8, LLDB_INVALID_REGNUM, 83, 83 }, g_d8_regs, nullptr, nullptr, 0 }, - { "d9", nullptr, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d9, LLDB_INVALID_REGNUM, 84, 84 }, g_d9_regs, nullptr, nullptr, 0 }, - { "d10", nullptr, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d10, LLDB_INVALID_REGNUM, 85, 85 }, g_d10_regs, nullptr, nullptr, 0 }, - { "d11", nullptr, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d11, LLDB_INVALID_REGNUM, 86, 86 }, g_d11_regs, nullptr, nullptr, 0 }, - { "d12", nullptr, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d12, LLDB_INVALID_REGNUM, 87, 87 }, g_d12_regs, nullptr, nullptr, 0 }, - { "d13", nullptr, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d13, LLDB_INVALID_REGNUM, 88, 88 }, g_d13_regs, nullptr, nullptr, 0 }, - { "d14", nullptr, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d14, LLDB_INVALID_REGNUM, 89, 89 }, g_d14_regs, nullptr, nullptr, 0 }, - { "d15", nullptr, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d15, LLDB_INVALID_REGNUM, 90, 90 }, g_d15_regs, nullptr, nullptr, 0 }, - { "q0", nullptr, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q0, LLDB_INVALID_REGNUM, 91, 91 }, g_q0_regs, nullptr, nullptr, 0 }, - { "q1", nullptr, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q1, LLDB_INVALID_REGNUM, 92, 92 }, g_q1_regs, nullptr, nullptr, 0 }, - { "q2", nullptr, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q2, LLDB_INVALID_REGNUM, 93, 93 }, g_q2_regs, nullptr, nullptr, 0 }, - { "q3", nullptr, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q3, LLDB_INVALID_REGNUM, 94, 94 }, g_q3_regs, nullptr, nullptr, 0 }, - { "q4", nullptr, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q4, LLDB_INVALID_REGNUM, 95, 95 }, g_q4_regs, nullptr, nullptr, 0 }, - { "q5", nullptr, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q5, LLDB_INVALID_REGNUM, 96, 96 }, g_q5_regs, nullptr, nullptr, 0 }, - { "q6", nullptr, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q6, LLDB_INVALID_REGNUM, 97, 97 }, g_q6_regs, nullptr, nullptr, 0 }, - { "q7", nullptr, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q7, LLDB_INVALID_REGNUM, 98, 98 }, g_q7_regs, nullptr, nullptr, 0 }, - { "q8", nullptr, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q8, LLDB_INVALID_REGNUM, 99, 99 }, g_q8_regs, nullptr, nullptr, 0 }, - { "q9", nullptr, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q9, LLDB_INVALID_REGNUM, 100, 100 }, g_q9_regs, nullptr, nullptr, 0 }, - { "q10", nullptr, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q10, LLDB_INVALID_REGNUM, 101, 101 }, g_q10_regs, nullptr, nullptr, 0 }, - { "q11", nullptr, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q11, LLDB_INVALID_REGNUM, 102, 102 }, g_q11_regs, nullptr, nullptr, 0 }, - { "q12", nullptr, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q12, LLDB_INVALID_REGNUM, 103, 103 }, g_q12_regs, nullptr, nullptr, 0 }, - { "q13", nullptr, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q13, LLDB_INVALID_REGNUM, 104, 104 }, g_q13_regs, nullptr, nullptr, 0 }, - { "q14", nullptr, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q14, LLDB_INVALID_REGNUM, 105, 105 }, g_q14_regs, nullptr, nullptr, 0 }, - { "q15", nullptr, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q15, LLDB_INVALID_REGNUM, 106, 106 }, g_q15_regs, nullptr, nullptr, 0 } - }; - // clang-format on - - static const uint32_t num_registers = llvm::array_lengthof(g_register_infos); - static ConstString gpr_reg_set("General Purpose Registers"); - static ConstString sfp_reg_set("Software Floating Point Registers"); - static ConstString vfp_reg_set("Floating Point Registers"); - size_t i; - if (from_scratch) { - // Calculate the offsets of the registers - // Note that the layout of the "composite" registers (d0-d15 and q0-q15) - // which comes after the "primordial" registers is important. This enables - // us to calculate the offset of the composite register by using the offset - // of its first primordial register. For example, to calculate the offset - // of q0, use s0's offset. - if (g_register_infos[2].byte_offset == 0) { - uint32_t byte_offset = 0; - for (i = 0; i < num_registers; ++i) { - // For primordial registers, increment the byte_offset by the byte_size - // to arrive at the byte_offset for the next register. Otherwise, we - // have a composite register whose offset can be calculated by - // consulting the offset of its first primordial register. - if (!g_register_infos[i].value_regs) { - g_register_infos[i].byte_offset = byte_offset; - byte_offset += g_register_infos[i].byte_size; - } else { - const uint32_t first_primordial_reg = - g_register_infos[i].value_regs[0]; - g_register_infos[i].byte_offset = - g_register_infos[first_primordial_reg].byte_offset; - } - } - } - for (i = 0; i < num_registers; ++i) { - ConstString name; - ConstString alt_name; - if (g_register_infos[i].name && g_register_infos[i].name[0]) - name.SetCString(g_register_infos[i].name); - if (g_register_infos[i].alt_name && g_register_infos[i].alt_name[0]) - alt_name.SetCString(g_register_infos[i].alt_name); - - if (i <= 15 || i == 25) - AddRegister(g_register_infos[i], name, alt_name, gpr_reg_set); - else if (i <= 24) - AddRegister(g_register_infos[i], name, alt_name, sfp_reg_set); - else - AddRegister(g_register_infos[i], name, alt_name, vfp_reg_set); - } - } else { - // Add composite registers to our primordial registers, then. - const size_t num_composites = llvm::array_lengthof(g_composites); - const size_t num_dynamic_regs = GetNumRegisters(); - const size_t num_common_regs = num_registers - num_composites; - RegisterInfo *g_comp_register_infos = g_register_infos + num_common_regs; - - // First we need to validate that all registers that we already have match - // the non composite regs. If so, then we can add the registers, else we - // need to bail - bool match = true; - if (num_dynamic_regs == num_common_regs) { - for (i = 0; match && i < num_dynamic_regs; ++i) { - // Make sure all register names match - if (m_regs[i].name && g_register_infos[i].name) { - if (strcmp(m_regs[i].name, g_register_infos[i].name)) { - match = false; - break; - } - } - - // Make sure all register byte sizes match - if (m_regs[i].byte_size != g_register_infos[i].byte_size) { - match = false; - break; - } - } - } else { - // Wrong number of registers. - match = false; - } - // If "match" is true, then we can add extra registers. - if (match) { - for (i = 0; i < num_composites; ++i) { - ConstString name; - ConstString alt_name; - const uint32_t first_primordial_reg = - g_comp_register_infos[i].value_regs[0]; - const char *reg_name = g_register_infos[first_primordial_reg].name; - if (reg_name && reg_name[0]) { - for (uint32_t j = 0; j < num_dynamic_regs; ++j) { - const RegisterInfo *reg_info = GetRegisterInfoAtIndex(j); - // Find a matching primordial register info entry. - if (reg_info && reg_info->name && - ::strcasecmp(reg_info->name, reg_name) == 0) { - // The name matches the existing primordial entry. Find and - // assign the offset, and then add this composite register entry. - g_comp_register_infos[i].byte_offset = reg_info->byte_offset; - name.SetCString(g_comp_register_infos[i].name); - AddRegister(g_comp_register_infos[i], name, alt_name, - vfp_reg_set); - } - } - } - } - } - } -} diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.h b/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.h index 18fcb73b9815..83c809c5aab6 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.h +++ b/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.h @@ -11,7 +11,7 @@ #include <vector> -#include "Plugins/Process/Utility/DynamicRegisterInfo.h" +#include "lldb/Target/DynamicRegisterInfo.h" #include "lldb/Target/RegisterContext.h" #include "lldb/Utility/ConstString.h" #include "lldb/Utility/DataExtractor.h" @@ -38,7 +38,6 @@ public: ~GDBRemoteDynamicRegisterInfo() override = default; - void HardcodeARMRegisters(bool from_scratch); bool UpdateARM64SVERegistersInfos(uint64_t vg); }; @@ -83,7 +82,7 @@ public: protected: friend class ThreadGDBRemote; - bool ReadRegisterBytes(const RegisterInfo *reg_info, DataExtractor &data); + bool ReadRegisterBytes(const RegisterInfo *reg_info); bool WriteRegisterBytes(const RegisterInfo *reg_info, DataExtractor &data, uint32_t data_offset); diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp index b8a737586eb4..6ed3f4fc3f59 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp @@ -43,7 +43,6 @@ #include "lldb/Host/HostThread.h" #include "lldb/Host/PosixApi.h" #include "lldb/Host/PseudoTerminal.h" -#include "lldb/Host/StringConvert.h" #include "lldb/Host/ThreadLauncher.h" #include "lldb/Host/XML.h" #include "lldb/Interpreter/CommandInterpreter.h" @@ -106,7 +105,7 @@ namespace lldb { // and get the packet history dumped to a file. void DumpProcessGDBRemotePacketHistory(void *p, const char *path) { auto file = FileSystem::Instance().Open( - FileSpec(path), File::eOpenOptionWrite | File::eOpenOptionCanCreate); + FileSpec(path), File::eOpenOptionWriteOnly | File::eOpenOptionCanCreate); if (!file) { llvm::consumeError(file.takeError()); return; @@ -129,7 +128,7 @@ enum { class PluginProperties : public Properties { public: static ConstString GetSettingName() { - return ProcessGDBRemote::GetPluginNameStatic(); + return ConstString(ProcessGDBRemote::GetPluginNameStatic()); } PluginProperties() : Properties() { @@ -168,13 +167,9 @@ public: } }; -typedef std::shared_ptr<PluginProperties> ProcessKDPPropertiesSP; - -static const ProcessKDPPropertiesSP &GetGlobalPluginProperties() { - static ProcessKDPPropertiesSP g_settings_sp; - if (!g_settings_sp) - g_settings_sp = std::make_shared<PluginProperties>(); - return g_settings_sp; +static PluginProperties &GetGlobalPluginProperties() { + static PluginProperties g_settings; + return g_settings; } } // namespace @@ -191,12 +186,7 @@ static const ProcessKDPPropertiesSP &GetGlobalPluginProperties() { #define HIGH_PORT (49151u) #endif -ConstString ProcessGDBRemote::GetPluginNameStatic() { - static ConstString g_name("gdb-remote"); - return g_name; -} - -const char *ProcessGDBRemote::GetPluginDescriptionStatic() { +llvm::StringRef ProcessGDBRemote::GetPluginDescriptionStatic() { return "GDB Remote protocol based debugging plug-in."; } @@ -216,7 +206,7 @@ ProcessGDBRemote::CreateInstance(lldb::TargetSP target_sp, } std::chrono::seconds ProcessGDBRemote::GetPacketTimeout() { - return std::chrono::seconds(GetGlobalPluginProperties()->GetPacketTimeout()); + return std::chrono::seconds(GetGlobalPluginProperties().GetPacketTimeout()); } bool ProcessGDBRemote::CanDebug(lldb::TargetSP target_sp, @@ -254,8 +244,7 @@ bool ProcessGDBRemote::CanDebug(lldb::TargetSP target_sp, ProcessGDBRemote::ProcessGDBRemote(lldb::TargetSP target_sp, ListenerSP listener_sp) : Process(target_sp, listener_sp), - m_debugserver_pid(LLDB_INVALID_PROCESS_ID), m_last_stop_packet_mutex(), - m_register_info_sp(nullptr), + m_debugserver_pid(LLDB_INVALID_PROCESS_ID), m_register_info_sp(nullptr), m_async_broadcaster(nullptr, "lldb.process.gdb-remote.async-broadcaster"), m_async_listener_sp( Listener::MakeListener("lldb.process.gdb-remote.async-listener")), @@ -267,7 +256,8 @@ ProcessGDBRemote::ProcessGDBRemote(lldb::TargetSP target_sp, m_waiting_for_attach(false), m_destroy_tried_resuming(false), m_command_sp(), m_breakpoint_pc_offset(0), m_initial_tid(LLDB_INVALID_THREAD_ID), m_replay_mode(false), - m_allow_flash_writes(false), m_erased_flash_ranges() { + m_allow_flash_writes(false), m_erased_flash_ranges(), + m_vfork_in_progress(false) { m_async_broadcaster.SetEventName(eBroadcastBitAsyncThreadShouldExit, "async thread should exit"); m_async_broadcaster.SetEventName(eBroadcastBitAsyncContinue, @@ -305,12 +295,12 @@ ProcessGDBRemote::ProcessGDBRemote(lldb::TargetSP target_sp, } const uint64_t timeout_seconds = - GetGlobalPluginProperties()->GetPacketTimeout(); + GetGlobalPluginProperties().GetPacketTimeout(); if (timeout_seconds > 0) m_gdb_comm.SetPacketTimeout(std::chrono::seconds(timeout_seconds)); m_use_g_packet_for_reading = - GetGlobalPluginProperties()->GetUseGPacketForReading(); + GetGlobalPluginProperties().GetUseGPacketForReading(); } // Destructor @@ -331,11 +321,6 @@ ProcessGDBRemote::~ProcessGDBRemote() { KillDebugserverProcess(); } -// PluginInterface -ConstString ProcessGDBRemote::GetPluginName() { return GetPluginNameStatic(); } - -uint32_t ProcessGDBRemote::GetPluginVersion() { return 1; } - bool ProcessGDBRemote::ParsePythonTargetDefinition( const FileSpec &target_definition_fspec) { ScriptInterpreter *interpreter = @@ -384,20 +369,14 @@ bool ProcessGDBRemote::ParsePythonTargetDefinition( } static size_t SplitCommaSeparatedRegisterNumberString( - const llvm::StringRef &comma_separated_regiter_numbers, + const llvm::StringRef &comma_separated_register_numbers, std::vector<uint32_t> ®nums, int base) { regnums.clear(); - std::pair<llvm::StringRef, llvm::StringRef> value_pair; - value_pair.second = comma_separated_regiter_numbers; - do { - value_pair = value_pair.second.split(','); - if (!value_pair.first.empty()) { - uint32_t reg = StringConvert::ToUInt32(value_pair.first.str().c_str(), - LLDB_INVALID_REGNUM, base); - if (reg != LLDB_INVALID_REGNUM) - regnums.push_back(reg); - } - } while (!value_pair.second.empty()); + for (llvm::StringRef x : llvm::split(comma_separated_register_numbers, ',')) { + uint32_t reg; + if (llvm::to_integer(x, reg, base)) + regnums.push_back(reg); + } return regnums.size(); } @@ -412,7 +391,7 @@ void ProcessGDBRemote::BuildDynamicRegisterInfo(bool force) { // timeout is and can see it. const auto host_packet_timeout = m_gdb_comm.GetHostDefaultPacketTimeout(); if (host_packet_timeout > std::chrono::seconds(0)) { - GetGlobalPluginProperties()->SetPacketTimeout(host_packet_timeout.count()); + GetGlobalPluginProperties().SetPacketTimeout(host_packet_timeout.count()); } // Register info search order: @@ -422,7 +401,7 @@ void ProcessGDBRemote::BuildDynamicRegisterInfo(bool force) { // 3 - Fall back on the qRegisterInfo packets. FileSpec target_definition_fspec = - GetGlobalPluginProperties()->GetTargetDefinitionFile(); + GetGlobalPluginProperties().GetTargetDefinitionFile(); if (!FileSystem::Instance().Exists(target_definition_fspec)) { // If the filename doesn't exist, it may be a ~ not having been expanded - // try to resolve it. @@ -457,7 +436,7 @@ void ProcessGDBRemote::BuildDynamicRegisterInfo(bool force) { return; char packet[128]; - uint32_t reg_offset = LLDB_INVALID_INDEX32; + std::vector<DynamicRegisterInfo::Register> registers; uint32_t reg_num = 0; for (StringExtractorGDBRemote::ResponseType response_type = StringExtractorGDBRemote::eResponse; @@ -473,53 +452,25 @@ void ProcessGDBRemote::BuildDynamicRegisterInfo(bool force) { if (response_type == StringExtractorGDBRemote::eResponse) { llvm::StringRef name; llvm::StringRef value; - ConstString reg_name; - ConstString alt_name; - ConstString set_name; - std::vector<uint32_t> value_regs; - std::vector<uint32_t> invalidate_regs; - std::vector<uint8_t> dwarf_opcode_bytes; - RegisterInfo reg_info = { - nullptr, // Name - nullptr, // Alt name - 0, // byte size - reg_offset, // offset - eEncodingUint, // encoding - eFormatHex, // format - { - LLDB_INVALID_REGNUM, // eh_frame reg num - LLDB_INVALID_REGNUM, // DWARF reg num - LLDB_INVALID_REGNUM, // generic reg num - reg_num, // process plugin reg num - reg_num // native register number - }, - nullptr, - nullptr, - nullptr, // Dwarf expression opcode bytes pointer - 0 // Dwarf expression opcode bytes length - }; + DynamicRegisterInfo::Register reg_info; while (response.GetNameColonValue(name, value)) { if (name.equals("name")) { - reg_name.SetString(value); + reg_info.name.SetString(value); } else if (name.equals("alt-name")) { - alt_name.SetString(value); + reg_info.alt_name.SetString(value); } else if (name.equals("bitsize")) { - value.getAsInteger(0, reg_info.byte_size); - reg_info.byte_size /= CHAR_BIT; + if (!value.getAsInteger(0, reg_info.byte_size)) + reg_info.byte_size /= CHAR_BIT; } else if (name.equals("offset")) { - if (value.getAsInteger(0, reg_offset)) - reg_offset = UINT32_MAX; + value.getAsInteger(0, reg_info.byte_offset); } else if (name.equals("encoding")) { const Encoding encoding = Args::StringToEncoding(value); if (encoding != eEncodingInvalid) reg_info.encoding = encoding; } else if (name.equals("format")) { - Format format = eFormatInvalid; - if (OptionArgParser::ToFormat(value.str().c_str(), format, nullptr) + if (!OptionArgParser::ToFormat(value.str().c_str(), reg_info.format, nullptr) .Success()) - reg_info.format = format; - else { reg_info.format = llvm::StringSwitch<Format>(value) .Case("binary", eFormatBinary) @@ -536,58 +487,23 @@ void ProcessGDBRemote::BuildDynamicRegisterInfo(bool force) { .Case("vector-uint64", eFormatVectorOfUInt64) .Case("vector-uint128", eFormatVectorOfUInt128) .Default(eFormatInvalid); - } } else if (name.equals("set")) { - set_name.SetString(value); + reg_info.set_name.SetString(value); } else if (name.equals("gcc") || name.equals("ehframe")) { - if (value.getAsInteger(0, reg_info.kinds[eRegisterKindEHFrame])) - reg_info.kinds[eRegisterKindEHFrame] = LLDB_INVALID_REGNUM; + value.getAsInteger(0, reg_info.regnum_ehframe); } else if (name.equals("dwarf")) { - if (value.getAsInteger(0, reg_info.kinds[eRegisterKindDWARF])) - reg_info.kinds[eRegisterKindDWARF] = LLDB_INVALID_REGNUM; + value.getAsInteger(0, reg_info.regnum_dwarf); } else if (name.equals("generic")) { - reg_info.kinds[eRegisterKindGeneric] = - Args::StringToGenericRegister(value); + reg_info.regnum_generic = Args::StringToGenericRegister(value); } else if (name.equals("container-regs")) { - SplitCommaSeparatedRegisterNumberString(value, value_regs, 16); + SplitCommaSeparatedRegisterNumberString(value, reg_info.value_regs, 16); } else if (name.equals("invalidate-regs")) { - SplitCommaSeparatedRegisterNumberString(value, invalidate_regs, 16); - } else if (name.equals("dynamic_size_dwarf_expr_bytes")) { - size_t dwarf_opcode_len = value.size() / 2; - assert(dwarf_opcode_len > 0); - - dwarf_opcode_bytes.resize(dwarf_opcode_len); - reg_info.dynamic_size_dwarf_len = dwarf_opcode_len; - - StringExtractor opcode_extractor(value); - uint32_t ret_val = - opcode_extractor.GetHexBytesAvail(dwarf_opcode_bytes); - assert(dwarf_opcode_len == ret_val); - UNUSED_IF_ASSERT_DISABLED(ret_val); - reg_info.dynamic_size_dwarf_expr_bytes = dwarf_opcode_bytes.data(); + SplitCommaSeparatedRegisterNumberString(value, reg_info.invalidate_regs, 16); } } - reg_info.byte_offset = reg_offset; assert(reg_info.byte_size != 0); - reg_offset = LLDB_INVALID_INDEX32; - if (!value_regs.empty()) { - value_regs.push_back(LLDB_INVALID_REGNUM); - reg_info.value_regs = value_regs.data(); - } - if (!invalidate_regs.empty()) { - invalidate_regs.push_back(LLDB_INVALID_REGNUM); - reg_info.invalidate_regs = invalidate_regs.data(); - } - - reg_info.name = reg_name.AsCString(); - // We have to make a temporary ABI here, and not use the GetABI because - // this code gets called in DidAttach, when the target architecture - // (and consequently the ABI we'll get from the process) may be wrong. - if (ABISP abi_sp = ABI::FindPlugin(shared_from_this(), arch_to_use)) - abi_sp->AugmentRegisterInfo(reg_info); - - m_register_info_sp->AddRegister(reg_info, reg_name, alt_name, set_name); + registers.push_back(reg_info); } else { break; // ensure exit before reg_num is incremented } @@ -596,31 +512,7 @@ void ProcessGDBRemote::BuildDynamicRegisterInfo(bool force) { } } - if (m_register_info_sp->GetNumRegisters() > 0) { - m_register_info_sp->Finalize(GetTarget().GetArchitecture()); - return; - } - - // We didn't get anything if the accumulated reg_num is zero. See if we are - // debugging ARM and fill with a hard coded register set until we can get an - // updated debugserver down on the devices. On the other hand, if the - // accumulated reg_num is positive, see if we can add composite registers to - // the existing primordial ones. - bool from_scratch = (m_register_info_sp->GetNumRegisters() == 0); - - if (!target_arch.IsValid()) { - if (arch_to_use.IsValid() && - (arch_to_use.GetMachine() == llvm::Triple::arm || - arch_to_use.GetMachine() == llvm::Triple::thumb) && - arch_to_use.GetTriple().getVendor() == llvm::Triple::Apple) - m_register_info_sp->HardcodeARMRegisters(from_scratch); - } else if (target_arch.GetMachine() == llvm::Triple::arm || - target_arch.GetMachine() == llvm::Triple::thumb) { - m_register_info_sp->HardcodeARMRegisters(from_scratch); - } - - // At this point, we can finalize our register info. - m_register_info_sp->Finalize(GetTarget().GetArchitecture()); + AddRemoteRegisters(registers, arch_to_use); } Status ProcessGDBRemote::WillLaunch(lldb_private::Module *module) { @@ -665,10 +557,6 @@ Status ProcessGDBRemote::DoConnectRemote(llvm::StringRef remote_url) { if (m_gdb_comm.GetStopReply(response)) { SetLastStopPacket(response); - // '?' Packets must be handled differently in non-stop mode - if (GetTarget().GetNonStopModeEnabled()) - HandleStopReplySequence(); - Target &target = GetTarget(); if (!target.GetArchitecture().IsValid()) { if (m_gdb_comm.GetProcessArchitecture().IsValid()) { @@ -721,14 +609,6 @@ Status ProcessGDBRemote::DoConnectRemote(llvm::StringRef remote_url) { __FUNCTION__, GetID(), GetTarget().GetArchitecture().GetTriple().getTriple().c_str()); - if (error.Success()) { - PlatformSP platform_sp = GetTarget().GetPlatform(); - if (platform_sp && platform_sp->IsConnected()) - SetUnixSignals(platform_sp->GetUnixSignals()); - else - SetUnixSignals(UnixSignals::Create(GetTarget().GetArchitecture())); - } - return error; } @@ -799,146 +679,133 @@ Status ProcessGDBRemote::DoLaunch(lldb_private::Module *exe_module, // LLDB_LOG_OPTION_PREPEND_PROC_AND_THREAD); // ::LogSetLogFile ("/dev/stdout"); - ObjectFile *object_file = exe_module->GetObjectFile(); - if (object_file) { - error = EstablishConnectionIfNeeded(launch_info); - if (error.Success()) { - PseudoTerminal pty; - const bool disable_stdio = (launch_flags & eLaunchFlagDisableSTDIO) != 0; - - PlatformSP platform_sp(GetTarget().GetPlatform()); - if (disable_stdio) { - // set to /dev/null unless redirected to a file above - if (!stdin_file_spec) - stdin_file_spec.SetFile(FileSystem::DEV_NULL, - FileSpec::Style::native); - if (!stdout_file_spec) - stdout_file_spec.SetFile(FileSystem::DEV_NULL, - FileSpec::Style::native); - if (!stderr_file_spec) - stderr_file_spec.SetFile(FileSystem::DEV_NULL, - FileSpec::Style::native); - } else if (platform_sp && platform_sp->IsHost()) { - // If the debugserver is local and we aren't disabling STDIO, lets use - // a pseudo terminal to instead of relying on the 'O' packets for stdio - // since 'O' packets can really slow down debugging if the inferior - // does a lot of output. - if ((!stdin_file_spec || !stdout_file_spec || !stderr_file_spec) && - !errorToBool(pty.OpenFirstAvailablePrimary(O_RDWR | O_NOCTTY))) { - FileSpec secondary_name(pty.GetSecondaryName()); - - if (!stdin_file_spec) - stdin_file_spec = secondary_name; - - if (!stdout_file_spec) - stdout_file_spec = secondary_name; - - if (!stderr_file_spec) - stderr_file_spec = secondary_name; - } - LLDB_LOGF( - log, - "ProcessGDBRemote::%s adjusted STDIO paths for local platform " - "(IsHost() is true) using secondary: stdin=%s, stdout=%s, " - "stderr=%s", - __FUNCTION__, - stdin_file_spec ? stdin_file_spec.GetCString() : "<null>", - stdout_file_spec ? stdout_file_spec.GetCString() : "<null>", - stderr_file_spec ? stderr_file_spec.GetCString() : "<null>"); - } - - LLDB_LOGF(log, - "ProcessGDBRemote::%s final STDIO paths after all " - "adjustments: stdin=%s, stdout=%s, stderr=%s", - __FUNCTION__, - stdin_file_spec ? stdin_file_spec.GetCString() : "<null>", - stdout_file_spec ? stdout_file_spec.GetCString() : "<null>", - stderr_file_spec ? stderr_file_spec.GetCString() : "<null>"); - - if (stdin_file_spec) - m_gdb_comm.SetSTDIN(stdin_file_spec); - if (stdout_file_spec) - m_gdb_comm.SetSTDOUT(stdout_file_spec); - if (stderr_file_spec) - m_gdb_comm.SetSTDERR(stderr_file_spec); + error = EstablishConnectionIfNeeded(launch_info); + if (error.Success()) { + PseudoTerminal pty; + const bool disable_stdio = (launch_flags & eLaunchFlagDisableSTDIO) != 0; - m_gdb_comm.SetDisableASLR(launch_flags & eLaunchFlagDisableASLR); - m_gdb_comm.SetDetachOnError(launch_flags & eLaunchFlagDetachOnError); + PlatformSP platform_sp(GetTarget().GetPlatform()); + if (disable_stdio) { + // set to /dev/null unless redirected to a file above + if (!stdin_file_spec) + stdin_file_spec.SetFile(FileSystem::DEV_NULL, + FileSpec::Style::native); + if (!stdout_file_spec) + stdout_file_spec.SetFile(FileSystem::DEV_NULL, + FileSpec::Style::native); + if (!stderr_file_spec) + stderr_file_spec.SetFile(FileSystem::DEV_NULL, + FileSpec::Style::native); + } else if (platform_sp && platform_sp->IsHost()) { + // If the debugserver is local and we aren't disabling STDIO, lets use + // a pseudo terminal to instead of relying on the 'O' packets for stdio + // since 'O' packets can really slow down debugging if the inferior + // does a lot of output. + if ((!stdin_file_spec || !stdout_file_spec || !stderr_file_spec) && + !errorToBool(pty.OpenFirstAvailablePrimary(O_RDWR | O_NOCTTY))) { + FileSpec secondary_name(pty.GetSecondaryName()); - m_gdb_comm.SendLaunchArchPacket( - GetTarget().GetArchitecture().GetArchitectureName()); + if (!stdin_file_spec) + stdin_file_spec = secondary_name; - const char *launch_event_data = launch_info.GetLaunchEventData(); - if (launch_event_data != nullptr && *launch_event_data != '\0') - m_gdb_comm.SendLaunchEventDataPacket(launch_event_data); + if (!stdout_file_spec) + stdout_file_spec = secondary_name; - if (working_dir) { - m_gdb_comm.SetWorkingDir(working_dir); + if (!stderr_file_spec) + stderr_file_spec = secondary_name; } + LLDB_LOGF( + log, + "ProcessGDBRemote::%s adjusted STDIO paths for local platform " + "(IsHost() is true) using secondary: stdin=%s, stdout=%s, " + "stderr=%s", + __FUNCTION__, + stdin_file_spec ? stdin_file_spec.GetCString() : "<null>", + stdout_file_spec ? stdout_file_spec.GetCString() : "<null>", + stderr_file_spec ? stderr_file_spec.GetCString() : "<null>"); + } - // Send the environment and the program + arguments after we connect - m_gdb_comm.SendEnvironment(launch_info.GetEnvironment()); + LLDB_LOGF(log, + "ProcessGDBRemote::%s final STDIO paths after all " + "adjustments: stdin=%s, stdout=%s, stderr=%s", + __FUNCTION__, + stdin_file_spec ? stdin_file_spec.GetCString() : "<null>", + stdout_file_spec ? stdout_file_spec.GetCString() : "<null>", + stderr_file_spec ? stderr_file_spec.GetCString() : "<null>"); + + if (stdin_file_spec) + m_gdb_comm.SetSTDIN(stdin_file_spec); + if (stdout_file_spec) + m_gdb_comm.SetSTDOUT(stdout_file_spec); + if (stderr_file_spec) + m_gdb_comm.SetSTDERR(stderr_file_spec); + + m_gdb_comm.SetDisableASLR(launch_flags & eLaunchFlagDisableASLR); + m_gdb_comm.SetDetachOnError(launch_flags & eLaunchFlagDetachOnError); + + m_gdb_comm.SendLaunchArchPacket( + GetTarget().GetArchitecture().GetArchitectureName()); + + const char *launch_event_data = launch_info.GetLaunchEventData(); + if (launch_event_data != nullptr && *launch_event_data != '\0') + m_gdb_comm.SendLaunchEventDataPacket(launch_event_data); + + if (working_dir) { + m_gdb_comm.SetWorkingDir(working_dir); + } - { - // Scope for the scoped timeout object - GDBRemoteCommunication::ScopedTimeout timeout(m_gdb_comm, - std::chrono::seconds(10)); + // Send the environment and the program + arguments after we connect + m_gdb_comm.SendEnvironment(launch_info.GetEnvironment()); - int arg_packet_err = m_gdb_comm.SendArgumentsPacket(launch_info); - if (arg_packet_err == 0) { - std::string error_str; - if (m_gdb_comm.GetLaunchSuccess(error_str)) { - SetID(m_gdb_comm.GetCurrentProcessID()); - } else { - error.SetErrorString(error_str.c_str()); - } + { + // Scope for the scoped timeout object + GDBRemoteCommunication::ScopedTimeout timeout(m_gdb_comm, + std::chrono::seconds(10)); + + int arg_packet_err = m_gdb_comm.SendArgumentsPacket(launch_info); + if (arg_packet_err == 0) { + std::string error_str; + if (m_gdb_comm.GetLaunchSuccess(error_str)) { + SetID(m_gdb_comm.GetCurrentProcessID()); } else { - error.SetErrorStringWithFormat("'A' packet returned an error: %i", - arg_packet_err); + error.SetErrorString(error_str.c_str()); } + } else { + error.SetErrorStringWithFormat("'A' packet returned an error: %i", + arg_packet_err); } + } - if (GetID() == LLDB_INVALID_PROCESS_ID) { - LLDB_LOGF(log, "failed to connect to debugserver: %s", - error.AsCString()); - KillDebugserverProcess(); - return error; - } + if (GetID() == LLDB_INVALID_PROCESS_ID) { + LLDB_LOGF(log, "failed to connect to debugserver: %s", + error.AsCString()); + KillDebugserverProcess(); + return error; + } - StringExtractorGDBRemote response; - if (m_gdb_comm.GetStopReply(response)) { - SetLastStopPacket(response); - // '?' Packets must be handled differently in non-stop mode - if (GetTarget().GetNonStopModeEnabled()) - HandleStopReplySequence(); + StringExtractorGDBRemote response; + if (m_gdb_comm.GetStopReply(response)) { + SetLastStopPacket(response); - const ArchSpec &process_arch = m_gdb_comm.GetProcessArchitecture(); + const ArchSpec &process_arch = m_gdb_comm.GetProcessArchitecture(); - if (process_arch.IsValid()) { - GetTarget().MergeArchitecture(process_arch); - } else { - const ArchSpec &host_arch = m_gdb_comm.GetHostArchitecture(); - if (host_arch.IsValid()) - GetTarget().MergeArchitecture(host_arch); - } + if (process_arch.IsValid()) { + GetTarget().MergeArchitecture(process_arch); + } else { + const ArchSpec &host_arch = m_gdb_comm.GetHostArchitecture(); + if (host_arch.IsValid()) + GetTarget().MergeArchitecture(host_arch); + } - SetPrivateState(SetThreadStopInfo(response)); + SetPrivateState(SetThreadStopInfo(response)); - if (!disable_stdio) { - if (pty.GetPrimaryFileDescriptor() != PseudoTerminal::invalid_fd) - SetSTDIOFileDescriptor(pty.ReleasePrimaryFileDescriptor()); - } + if (!disable_stdio) { + if (pty.GetPrimaryFileDescriptor() != PseudoTerminal::invalid_fd) + SetSTDIOFileDescriptor(pty.ReleasePrimaryFileDescriptor()); } - } else { - LLDB_LOGF(log, "failed to connect to debugserver: %s", error.AsCString()); } } else { - // Set our user ID to an invalid process ID. - SetID(LLDB_INVALID_PROCESS_ID); - error.SetErrorStringWithFormat( - "failed to get object file from '%s' for arch %s", - exe_module->GetFileSpec().GetFilename().AsCString(), - exe_module->GetArchitecture().GetArchitectureName()); + LLDB_LOGF(log, "failed to connect to debugserver: %s", error.AsCString()); } return error; } @@ -960,9 +827,6 @@ Status ProcessGDBRemote::ConnectToDebugserver(llvm::StringRef connect_url) { if (conn_up->Connect(connect_url, &error) == eConnectionStatusSuccess) { m_gdb_comm.SetConnection(std::move(conn_up)); break; - } else if (error.WasInterrupted()) { - // If we were interrupted, don't keep retrying. - break; } retry_count++; @@ -981,11 +845,6 @@ Status ProcessGDBRemote::ConnectToDebugserver(llvm::StringRef connect_url) { return error; } - // Start the communications read thread so all incoming data can be parsed - // into packets and queued as they arrive. - if (GetTarget().GetNonStopModeEnabled()) - m_gdb_comm.StartReadThread(); - // We always seem to be able to open a connection to a local port so we need // to make sure we can then send data to it. If we can't then we aren't // actually connected to anything, so try and do the handshake with the @@ -997,10 +856,6 @@ Status ProcessGDBRemote::ConnectToDebugserver(llvm::StringRef connect_url) { return error; } - // Send $QNonStop:1 packet on startup if required - if (GetTarget().GetNonStopModeEnabled()) - GetTarget().SetNonStopModeEnabled(m_gdb_comm.SetNonStopMode(true)); - m_gdb_comm.GetEchoSupported(); m_gdb_comm.GetThreadSuffixSupported(); m_gdb_comm.GetListThreadsInStopReplySupported(); @@ -1009,10 +864,6 @@ Status ProcessGDBRemote::ConnectToDebugserver(llvm::StringRef connect_url) { m_gdb_comm.GetVAttachOrWaitSupported(); m_gdb_comm.EnableErrorStringInPacket(); - // Ask the remote server for the default thread id - if (GetTarget().GetNonStopModeEnabled()) - m_gdb_comm.GetDefaultThreadId(m_initial_tid); - size_t num_cmds = GetExtraStartupCommands().GetArgumentCount(); for (size_t idx = 0; idx < num_cmds; idx++) { StringExtractorGDBRemote response; @@ -1113,6 +964,18 @@ void ProcessGDBRemote::DidLaunchOrAttach(ArchSpec &process_arch) { if (StructuredData::Array *supported_packets = m_gdb_comm.GetSupportedStructuredDataPlugins()) MapSupportedStructuredDataPlugins(*supported_packets); + + // If connected to LLDB ("native-signals+"), use signal defs for + // the remote platform. If connected to GDB, just use the standard set. + if (!m_gdb_comm.UsesNativeSignals()) { + SetUnixSignals(std::make_shared<GDBRemoteSignals>()); + } else { + PlatformSP platform_sp = GetTarget().GetPlatform(); + if (platform_sp && platform_sp->IsConnected()) + SetUnixSignals(platform_sp->GetUnixSignals()); + else + SetUnixSignals(UnixSignals::Create(GetTarget().GetArchitecture())); + } } void ProcessGDBRemote::MaybeLoadExecutableModule() { @@ -1272,10 +1135,9 @@ Status ProcessGDBRemote::DoResume() { StreamString continue_packet; bool continue_packet_error = false; if (m_gdb_comm.HasAnyVContSupport()) { - if (!GetTarget().GetNonStopModeEnabled() && - (m_continue_c_tids.size() == num_threads || - (m_continue_c_tids.empty() && m_continue_C_tids.empty() && - m_continue_s_tids.empty() && m_continue_S_tids.empty()))) { + if (m_continue_c_tids.size() == num_threads || + (m_continue_c_tids.empty() && m_continue_C_tids.empty() && + m_continue_s_tids.empty() && m_continue_S_tids.empty())) { // All threads are continuing, just send a "c" packet continue_packet.PutCString("c"); } else { @@ -1393,14 +1255,7 @@ Status ProcessGDBRemote::DoResume() { // All threads are resuming... m_gdb_comm.SetCurrentThreadForRun(-1); - // If in Non-Stop-Mode use vCont when stepping - if (GetTarget().GetNonStopModeEnabled()) { - if (m_gdb_comm.GetVContSupported('s')) - continue_packet.PutCString("vCont;s"); - else - continue_packet.PutChar('s'); - } else - continue_packet.PutChar('s'); + continue_packet.PutChar('s'); continue_packet_error = false; } else if (num_continue_c_tids == 0 && num_continue_C_tids == 0 && @@ -1514,21 +1369,14 @@ size_t ProcessGDBRemote::UpdateThreadIDsFromStopReplyThreadsValue( return m_thread_ids.size(); } -size_t -ProcessGDBRemote::UpdateThreadPCsFromStopReplyThreadsValue(std::string &value) { +size_t ProcessGDBRemote::UpdateThreadPCsFromStopReplyThreadsValue( + llvm::StringRef value) { m_thread_pcs.clear(); - size_t comma_pos; - lldb::addr_t pc; - while ((comma_pos = value.find(',')) != std::string::npos) { - value[comma_pos] = '\0'; - pc = StringConvert::ToUInt64(value.c_str(), LLDB_INVALID_ADDRESS, 16); - if (pc != LLDB_INVALID_ADDRESS) + for (llvm::StringRef x : llvm::split(value, ',')) { + lldb::addr_t pc; + if (llvm::to_integer(x, pc, 16)) m_thread_pcs.push_back(pc); - value.erase(0, comma_pos + 1); } - pc = StringConvert::ToUInt64(value.c_str(), LLDB_INVALID_ADDRESS, 16); - if (pc != LLDB_INVALID_ADDRESS) - m_thread_pcs.push_back(pc); return m_thread_pcs.size(); } @@ -1559,40 +1407,30 @@ bool ProcessGDBRemote::UpdateThreadIDList() { // See if we can get the thread IDs from the current stop reply packets // that might contain a "threads" key/value pair - // Lock the thread stack while we access it - // Mutex::Locker stop_stack_lock(m_last_stop_packet_mutex); - std::unique_lock<std::recursive_mutex> stop_stack_lock( - m_last_stop_packet_mutex, std::defer_lock); - if (stop_stack_lock.try_lock()) { - // Get the number of stop packets on the stack - int nItems = m_stop_packet_stack.size(); - // Iterate over them - for (int i = 0; i < nItems; i++) { - // Get the thread stop info - StringExtractorGDBRemote &stop_info = m_stop_packet_stack[i]; - const std::string &stop_info_str = - std::string(stop_info.GetStringRef()); + if (m_last_stop_packet) { + // Get the thread stop info + StringExtractorGDBRemote &stop_info = *m_last_stop_packet; + const std::string &stop_info_str = std::string(stop_info.GetStringRef()); - m_thread_pcs.clear(); - const size_t thread_pcs_pos = stop_info_str.find(";thread-pcs:"); - if (thread_pcs_pos != std::string::npos) { - const size_t start = thread_pcs_pos + strlen(";thread-pcs:"); - const size_t end = stop_info_str.find(';', start); - if (end != std::string::npos) { - std::string value = stop_info_str.substr(start, end - start); - UpdateThreadPCsFromStopReplyThreadsValue(value); - } + m_thread_pcs.clear(); + const size_t thread_pcs_pos = stop_info_str.find(";thread-pcs:"); + if (thread_pcs_pos != std::string::npos) { + const size_t start = thread_pcs_pos + strlen(";thread-pcs:"); + const size_t end = stop_info_str.find(';', start); + if (end != std::string::npos) { + std::string value = stop_info_str.substr(start, end - start); + UpdateThreadPCsFromStopReplyThreadsValue(value); } + } - const size_t threads_pos = stop_info_str.find(";threads:"); - if (threads_pos != std::string::npos) { - const size_t start = threads_pos + strlen(";threads:"); - const size_t end = stop_info_str.find(';', start); - if (end != std::string::npos) { - std::string value = stop_info_str.substr(start, end - start); - if (UpdateThreadIDsFromStopReplyThreadsValue(value)) - return true; - } + const size_t threads_pos = stop_info_str.find(";threads:"); + if (threads_pos != std::string::npos) { + const size_t start = threads_pos + strlen(";threads:"); + const size_t end = stop_info_str.find(';', start); + if (end != std::string::npos) { + std::string value = stop_info_str.substr(start, end - start); + if (UpdateThreadIDsFromStopReplyThreadsValue(value)) + return true; } } } @@ -1908,6 +1746,28 @@ ThreadSP ProcessGDBRemote::SetThreadStopInfo( } else if (reason == "processor trace") { thread_sp->SetStopInfo(StopInfo::CreateStopReasonProcessorTrace( *thread_sp, description.c_str())); + } else if (reason == "fork") { + StringExtractor desc_extractor(description.c_str()); + lldb::pid_t child_pid = desc_extractor.GetU64( + LLDB_INVALID_PROCESS_ID); + lldb::tid_t child_tid = desc_extractor.GetU64( + LLDB_INVALID_THREAD_ID); + thread_sp->SetStopInfo(StopInfo::CreateStopReasonFork( + *thread_sp, child_pid, child_tid)); + handled = true; + } else if (reason == "vfork") { + StringExtractor desc_extractor(description.c_str()); + lldb::pid_t child_pid = desc_extractor.GetU64( + LLDB_INVALID_PROCESS_ID); + lldb::tid_t child_tid = desc_extractor.GetU64( + LLDB_INVALID_THREAD_ID); + thread_sp->SetStopInfo(StopInfo::CreateStopReasonVFork( + *thread_sp, child_pid, child_tid)); + handled = true; + } else if (reason == "vforkdone") { + thread_sp->SetStopInfo( + StopInfo::CreateStopReasonVForkDone(*thread_sp)); + handled = true; } } else if (!signo) { addr_t pc = thread_sp->GetRegisterContext()->GetPC(); @@ -2032,6 +1892,7 @@ ProcessGDBRemote::SetThreadStopInfo(StructuredData::Dictionary *thread_dict) { // Iterate through all of the thread dictionary key/value pairs from the // structured data dictionary + // FIXME: we're silently ignoring invalid data here thread_dict->ForEach([this, &tid, &expedited_register_map, &thread_name, &signo, &reason, &description, &exc_type, &exc_data, &thread_dispatch_qaddr, &queue_vars_valid, @@ -2096,9 +1957,8 @@ ProcessGDBRemote::SetThreadStopInfo(StructuredData::Dictionary *thread_dict) { registers_dict->ForEach( [&expedited_register_map](ConstString key, StructuredData::Object *object) -> bool { - const uint32_t reg = - StringConvert::ToUInt32(key.GetCString(), UINT32_MAX, 10); - if (reg != UINT32_MAX) + uint32_t reg; + if (llvm::to_integer(key.AsCString(), reg)) expedited_register_map[reg] = std::string(object->GetStringValue()); return true; // Keep iterating through all array items @@ -2314,6 +2174,21 @@ StateType ProcessGDBRemote::SetThreadStopInfo(StringExtractor &stop_packet) { ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS)); LLDB_LOG_ERROR(log, std::move(error), "Failed to load modules: {0}"); } + } else if (key.compare("fork") == 0 || key.compare("vfork") == 0) { + // fork includes child pid/tid in thread-id format + StringExtractorGDBRemote thread_id{value}; + auto pid_tid = thread_id.GetPidTid(LLDB_INVALID_PROCESS_ID); + if (!pid_tid) { + Log *log( + ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS)); + LLDB_LOG(log, "Invalid PID/TID to fork: {0}", value); + pid_tid = {{LLDB_INVALID_PROCESS_ID, LLDB_INVALID_THREAD_ID}}; + } + + reason = key.str(); + StreamString ostr; + ostr.Printf("%" PRIu64 " %" PRIu64, pid_tid->first, pid_tid->second); + description = std::string(ostr.GetString()); } else if (key.size() == 2 && ::isxdigit(key[0]) && ::isxdigit(key[1])) { uint32_t reg = UINT32_MAX; if (!key.getAsInteger(16, reg)) @@ -2380,22 +2255,9 @@ void ProcessGDBRemote::RefreshStateAfterStop() { // date before we do that or we might overwrite what was computed here. UpdateThreadListIfNeeded(); - // Scope for the lock - { - // Lock the thread stack while we access it - std::lock_guard<std::recursive_mutex> guard(m_last_stop_packet_mutex); - // Get the number of stop packets on the stack - int nItems = m_stop_packet_stack.size(); - // Iterate over them - for (int i = 0; i < nItems; i++) { - // Get the thread stop info - StringExtractorGDBRemote stop_info = m_stop_packet_stack[i]; - // Process thread stop info - SetThreadStopInfo(stop_info); - } - // Clear the thread stop stack - m_stop_packet_stack.clear(); - } + if (m_last_stop_packet) + SetThreadStopInfo(*m_last_stop_packet); + m_last_stop_packet.reset(); // If we have queried for a default thread id if (m_initial_tid != LLDB_INVALID_THREAD_ID) { @@ -2479,9 +2341,9 @@ Status ProcessGDBRemote::DoDestroy() { m_public_state.GetValue() != eStateRunning) { PlatformSP platform_sp = GetTarget().GetPlatform(); - // FIXME: These should be ConstStrings so we aren't doing strcmp'ing. if (platform_sp && platform_sp->GetName() && - platform_sp->GetName() == PlatformRemoteiOS::GetPluginNameStatic()) { + platform_sp->GetName().GetStringRef() == + PlatformRemoteiOS::GetPluginNameStatic()) { if (m_destroy_tried_resuming) { if (log) log->PutCString("ProcessGDBRemote::DoDestroy() - Tried resuming to " @@ -2644,20 +2506,7 @@ void ProcessGDBRemote::SetLastStopPacket( m_gdb_comm.ResetDiscoverableSettings(did_exec); } - // Scope the lock - { - // Lock the thread stack while we access it - std::lock_guard<std::recursive_mutex> guard(m_last_stop_packet_mutex); - - // We are are not using non-stop mode, there can only be one last stop - // reply packet, so clear the list. - if (!GetTarget().GetNonStopModeEnabled()) - m_stop_packet_stack.clear(); - - // Add this stop packet to the stop packet stack This stack will get popped - // and examined when we switch to the Stopped state - m_stop_packet_stack.push_back(response); - } + m_last_stop_packet = response; } void ProcessGDBRemote::SetUnixSignals(const UnixSignalsSP &signals_sp) { @@ -3052,8 +2901,8 @@ lldb::addr_t ProcessGDBRemote::DoAllocateMemory(size_t size, return allocated_addr; } -Status ProcessGDBRemote::GetMemoryRegionInfo(addr_t load_addr, - MemoryRegionInfo ®ion_info) { +Status ProcessGDBRemote::DoGetMemoryRegionInfo(addr_t load_addr, + MemoryRegionInfo ®ion_info) { Status error(m_gdb_comm.GetMemoryRegionInfo(load_addr, region_info)); return error; @@ -3638,7 +3487,7 @@ void ProcessGDBRemote::DebuggerInitialize(Debugger &debugger) { debugger, PluginProperties::GetSettingName())) { const bool is_global_setting = true; PluginManager::CreateSettingForProcessPlugin( - debugger, GetGlobalPluginProperties()->GetValueProperties(), + debugger, GetGlobalPluginProperties().GetValueProperties(), ConstString("Properties for the gdb-remote process plug-in."), is_global_setting); } @@ -3774,88 +3623,72 @@ thread_result_t ProcessGDBRemote::AsyncThread(void *arg) { process->SetPrivateState(eStateRunning); StringExtractorGDBRemote response; - // If in Non-Stop-Mode - if (process->GetTarget().GetNonStopModeEnabled()) { - // send the vCont packet - if (!process->GetGDBRemote().SendvContPacket( - llvm::StringRef(continue_cstr, continue_cstr_len), - process->GetInterruptTimeout(), response)) { - // Something went wrong - done = true; - break; - } - } - // If in All-Stop-Mode - else { - StateType stop_state = - process->GetGDBRemote().SendContinuePacketAndWaitForResponse( - *process, *process->GetUnixSignals(), - llvm::StringRef(continue_cstr, continue_cstr_len), - process->GetInterruptTimeout(), - response); - - // We need to immediately clear the thread ID list so we are sure - // to get a valid list of threads. The thread ID list might be - // contained within the "response", or the stop reply packet that - // caused the stop. So clear it now before we give the stop reply - // packet to the process using the - // process->SetLastStopPacket()... - process->ClearThreadIDList(); + StateType stop_state = + process->GetGDBRemote().SendContinuePacketAndWaitForResponse( + *process, *process->GetUnixSignals(), + llvm::StringRef(continue_cstr, continue_cstr_len), + process->GetInterruptTimeout(), response); + + // We need to immediately clear the thread ID list so we are sure + // to get a valid list of threads. The thread ID list might be + // contained within the "response", or the stop reply packet that + // caused the stop. So clear it now before we give the stop reply + // packet to the process using the + // process->SetLastStopPacket()... + process->ClearThreadIDList(); + + switch (stop_state) { + case eStateStopped: + case eStateCrashed: + case eStateSuspended: + process->SetLastStopPacket(response); + process->SetPrivateState(stop_state); + break; - switch (stop_state) { - case eStateStopped: - case eStateCrashed: - case eStateSuspended: - process->SetLastStopPacket(response); - process->SetPrivateState(stop_state); - break; - - case eStateExited: { - process->SetLastStopPacket(response); - process->ClearThreadIDList(); - response.SetFilePos(1); - - int exit_status = response.GetHexU8(); - std::string desc_string; - if (response.GetBytesLeft() > 0 && - response.GetChar('-') == ';') { - llvm::StringRef desc_str; - llvm::StringRef desc_token; - while (response.GetNameColonValue(desc_token, desc_str)) { - if (desc_token != "description") - continue; - StringExtractor extractor(desc_str); - extractor.GetHexByteString(desc_string); - } + case eStateExited: { + process->SetLastStopPacket(response); + process->ClearThreadIDList(); + response.SetFilePos(1); + + int exit_status = response.GetHexU8(); + std::string desc_string; + if (response.GetBytesLeft() > 0 && response.GetChar('-') == ';') { + llvm::StringRef desc_str; + llvm::StringRef desc_token; + while (response.GetNameColonValue(desc_token, desc_str)) { + if (desc_token != "description") + continue; + StringExtractor extractor(desc_str); + extractor.GetHexByteString(desc_string); } - process->SetExitStatus(exit_status, desc_string.c_str()); - done = true; - break; } - case eStateInvalid: { - // Check to see if we were trying to attach and if we got back - // the "E87" error code from debugserver -- this indicates that - // the process is not debuggable. Return a slightly more - // helpful error message about why the attach failed. - if (::strstr(continue_cstr, "vAttach") != nullptr && - response.GetError() == 0x87) { - process->SetExitStatus(-1, "cannot attach to process due to " - "System Integrity Protection"); - } else if (::strstr(continue_cstr, "vAttach") != nullptr && - response.GetStatus().Fail()) { - process->SetExitStatus(-1, response.GetStatus().AsCString()); - } else { - process->SetExitStatus(-1, "lost connection"); - } - done = true; - break; + process->SetExitStatus(exit_status, desc_string.c_str()); + done = true; + break; + } + case eStateInvalid: { + // Check to see if we were trying to attach and if we got back + // the "E87" error code from debugserver -- this indicates that + // the process is not debuggable. Return a slightly more + // helpful error message about why the attach failed. + if (::strstr(continue_cstr, "vAttach") != nullptr && + response.GetError() == 0x87) { + process->SetExitStatus(-1, "cannot attach to process due to " + "System Integrity Protection"); + } else if (::strstr(continue_cstr, "vAttach") != nullptr && + response.GetStatus().Fail()) { + process->SetExitStatus(-1, response.GetStatus().AsCString()); + } else { + process->SetExitStatus(-1, "lost connection"); } + done = true; + break; + } - default: - process->SetPrivateState(stop_state); - break; - } // switch(stop_state) - } // else // if in All-stop-mode + default: + process->SetPrivateState(stop_state); + break; + } // switch(stop_state) } // if (continue_packet) } // case eBroadcastBitAsyncContinue break; @@ -4027,7 +3860,7 @@ bool ProcessGDBRemote::StopNoticingNewThreads() { DynamicLoader *ProcessGDBRemote::GetDynamicLoader() { if (m_dyld_up.get() == nullptr) - m_dyld_up.reset(DynamicLoader::FindPlugin(this, nullptr)); + m_dyld_up.reset(DynamicLoader::FindPlugin(this, "")); return m_dyld_up.get(); } @@ -4051,12 +3884,14 @@ Status ProcessGDBRemote::SendEventData(const char *data) { DataExtractor ProcessGDBRemote::GetAuxvData() { DataBufferSP buf; if (m_gdb_comm.GetQXferAuxvReadSupported()) { - std::string response_string; - if (m_gdb_comm.SendPacketsAndConcatenateResponses("qXfer:auxv:read::", - response_string) == - GDBRemoteCommunication::PacketResult::Success) - buf = std::make_shared<DataBufferHeap>(response_string.c_str(), - response_string.length()); + llvm::Expected<std::string> response = m_gdb_comm.ReadExtFeature("auxv", ""); + if (response) + buf = std::make_shared<DataBufferHeap>(response->c_str(), + response->length()); + else + LLDB_LOG_ERROR( + ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet(GDBR_LOG_PROCESS), + response.takeError(), "{0}"); } return DataExtractor(buf, GetByteOrder(), GetAddressByteSize()); } @@ -4351,132 +4186,84 @@ struct GdbServerTargetInfo { }; bool ParseRegisters(XMLNode feature_node, GdbServerTargetInfo &target_info, - GDBRemoteDynamicRegisterInfo &dyn_reg_info, ABISP abi_sp, - uint32_t ®_num_remote, uint32_t ®_num_local) { + std::vector<DynamicRegisterInfo::Register> ®isters) { if (!feature_node) return false; - uint32_t reg_offset = LLDB_INVALID_INDEX32; feature_node.ForEachChildElementWithName( - "reg", [&target_info, &dyn_reg_info, ®_num_remote, ®_num_local, - ®_offset, &abi_sp](const XMLNode ®_node) -> bool { + "reg", [&target_info, ®isters](const XMLNode ®_node) -> bool { std::string gdb_group; std::string gdb_type; - ConstString reg_name; - ConstString alt_name; - ConstString set_name; - std::vector<uint32_t> value_regs; - std::vector<uint32_t> invalidate_regs; - std::vector<uint8_t> dwarf_opcode_bytes; + DynamicRegisterInfo::Register reg_info; bool encoding_set = false; bool format_set = false; - RegisterInfo reg_info = { - nullptr, // Name - nullptr, // Alt name - 0, // byte size - reg_offset, // offset - eEncodingUint, // encoding - eFormatHex, // format - { - LLDB_INVALID_REGNUM, // eh_frame reg num - LLDB_INVALID_REGNUM, // DWARF reg num - LLDB_INVALID_REGNUM, // generic reg num - reg_num_remote, // process plugin reg num - reg_num_local // native register number - }, - nullptr, - nullptr, - nullptr, // Dwarf Expression opcode bytes pointer - 0 // Dwarf Expression opcode bytes length - }; + // FIXME: we're silently ignoring invalid data here reg_node.ForEachAttribute([&target_info, &gdb_group, &gdb_type, - ®_name, &alt_name, &set_name, &value_regs, - &invalidate_regs, &encoding_set, &format_set, - ®_info, ®_offset, &dwarf_opcode_bytes]( + &encoding_set, &format_set, ®_info]( const llvm::StringRef &name, const llvm::StringRef &value) -> bool { if (name == "name") { - reg_name.SetString(value); + reg_info.name.SetString(value); } else if (name == "bitsize") { - reg_info.byte_size = - StringConvert::ToUInt32(value.data(), 0, 0) / CHAR_BIT; + if (llvm::to_integer(value, reg_info.byte_size)) + reg_info.byte_size = + llvm::divideCeil(reg_info.byte_size, CHAR_BIT); } else if (name == "type") { gdb_type = value.str(); } else if (name == "group") { gdb_group = value.str(); } else if (name == "regnum") { - const uint32_t regnum = - StringConvert::ToUInt32(value.data(), LLDB_INVALID_REGNUM, 0); - if (regnum != LLDB_INVALID_REGNUM) { - reg_info.kinds[eRegisterKindProcessPlugin] = regnum; - } + llvm::to_integer(value, reg_info.regnum_remote); } else if (name == "offset") { - reg_offset = StringConvert::ToUInt32(value.data(), UINT32_MAX, 0); + llvm::to_integer(value, reg_info.byte_offset); } else if (name == "altname") { - alt_name.SetString(value); + reg_info.alt_name.SetString(value); } else if (name == "encoding") { encoding_set = true; reg_info.encoding = Args::StringToEncoding(value, eEncodingUint); } else if (name == "format") { format_set = true; - Format format = eFormatInvalid; - if (OptionArgParser::ToFormat(value.data(), format, nullptr) - .Success()) - reg_info.format = format; - else if (value == "vector-sint8") - reg_info.format = eFormatVectorOfSInt8; - else if (value == "vector-uint8") - reg_info.format = eFormatVectorOfUInt8; - else if (value == "vector-sint16") - reg_info.format = eFormatVectorOfSInt16; - else if (value == "vector-uint16") - reg_info.format = eFormatVectorOfUInt16; - else if (value == "vector-sint32") - reg_info.format = eFormatVectorOfSInt32; - else if (value == "vector-uint32") - reg_info.format = eFormatVectorOfUInt32; - else if (value == "vector-float32") - reg_info.format = eFormatVectorOfFloat32; - else if (value == "vector-uint64") - reg_info.format = eFormatVectorOfUInt64; - else if (value == "vector-uint128") - reg_info.format = eFormatVectorOfUInt128; + if (!OptionArgParser::ToFormat(value.data(), reg_info.format, + nullptr) + .Success()) + reg_info.format = + llvm::StringSwitch<lldb::Format>(value) + .Case("vector-sint8", eFormatVectorOfSInt8) + .Case("vector-uint8", eFormatVectorOfUInt8) + .Case("vector-sint16", eFormatVectorOfSInt16) + .Case("vector-uint16", eFormatVectorOfUInt16) + .Case("vector-sint32", eFormatVectorOfSInt32) + .Case("vector-uint32", eFormatVectorOfUInt32) + .Case("vector-float32", eFormatVectorOfFloat32) + .Case("vector-uint64", eFormatVectorOfUInt64) + .Case("vector-uint128", eFormatVectorOfUInt128) + .Default(eFormatInvalid); } else if (name == "group_id") { - const uint32_t set_id = - StringConvert::ToUInt32(value.data(), UINT32_MAX, 0); + uint32_t set_id = UINT32_MAX; + llvm::to_integer(value, set_id); RegisterSetMap::const_iterator pos = target_info.reg_set_map.find(set_id); if (pos != target_info.reg_set_map.end()) - set_name = pos->second.name; + reg_info.set_name = pos->second.name; } else if (name == "gcc_regnum" || name == "ehframe_regnum") { - reg_info.kinds[eRegisterKindEHFrame] = - StringConvert::ToUInt32(value.data(), LLDB_INVALID_REGNUM, 0); + llvm::to_integer(value, reg_info.regnum_ehframe); } else if (name == "dwarf_regnum") { - reg_info.kinds[eRegisterKindDWARF] = - StringConvert::ToUInt32(value.data(), LLDB_INVALID_REGNUM, 0); + llvm::to_integer(value, reg_info.regnum_dwarf); } else if (name == "generic") { - reg_info.kinds[eRegisterKindGeneric] = - Args::StringToGenericRegister(value); + reg_info.regnum_generic = Args::StringToGenericRegister(value); } else if (name == "value_regnums") { - SplitCommaSeparatedRegisterNumberString(value, value_regs, 0); + SplitCommaSeparatedRegisterNumberString(value, reg_info.value_regs, + 0); } else if (name == "invalidate_regnums") { - SplitCommaSeparatedRegisterNumberString(value, invalidate_regs, 0); - } else if (name == "dynamic_size_dwarf_expr_bytes") { - std::string opcode_string = value.str(); - size_t dwarf_opcode_len = opcode_string.length() / 2; - assert(dwarf_opcode_len > 0); - - dwarf_opcode_bytes.resize(dwarf_opcode_len); - reg_info.dynamic_size_dwarf_len = dwarf_opcode_len; - StringExtractor opcode_extractor(opcode_string); - uint32_t ret_val = - opcode_extractor.GetHexBytesAvail(dwarf_opcode_bytes); - assert(dwarf_opcode_len == ret_val); - UNUSED_IF_ASSERT_DISABLED(ret_val); - reg_info.dynamic_size_dwarf_expr_bytes = dwarf_opcode_bytes.data(); + SplitCommaSeparatedRegisterNumberString( + value, reg_info.invalidate_regs, 0); } else { - printf("unhandled attribute %s = %s\n", name.data(), value.data()); + Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet( + GDBR_LOG_PROCESS)); + LLDB_LOGF(log, + "ProcessGDBRemote::%s unhandled reg attribute %s = %s", + __FUNCTION__, name.data(), value.data()); } return true; // Keep iterating through all attributes }); @@ -4488,43 +4275,40 @@ bool ParseRegisters(XMLNode feature_node, GdbServerTargetInfo &target_info, } else if (gdb_type == "data_ptr" || gdb_type == "code_ptr") { reg_info.format = eFormatAddressInfo; reg_info.encoding = eEncodingUint; - } else if (gdb_type == "i387_ext" || gdb_type == "float") { + } else if (gdb_type == "float") { reg_info.format = eFormatFloat; reg_info.encoding = eEncodingIEEE754; + } else if (gdb_type == "aarch64v" || + llvm::StringRef(gdb_type).startswith("vec") || + gdb_type == "i387_ext" || gdb_type == "uint128") { + // lldb doesn't handle 128-bit uints correctly (for ymm*h), so treat + // them as vector (similarly to xmm/ymm) + reg_info.format = eFormatVectorOfUInt8; + reg_info.encoding = eEncodingVector; } } // Only update the register set name if we didn't get a "reg_set" // attribute. "set_name" will be empty if we didn't have a "reg_set" // attribute. - if (!set_name) { + if (!reg_info.set_name) { if (!gdb_group.empty()) { - set_name.SetCString(gdb_group.c_str()); + reg_info.set_name.SetCString(gdb_group.c_str()); } else { // If no register group name provided anywhere, // we'll create a 'general' register set - set_name.SetCString("general"); + reg_info.set_name.SetCString("general"); } } - reg_info.byte_offset = reg_offset; - assert(reg_info.byte_size != 0); - reg_offset = LLDB_INVALID_INDEX32; - if (!value_regs.empty()) { - value_regs.push_back(LLDB_INVALID_REGNUM); - reg_info.value_regs = value_regs.data(); - } - if (!invalidate_regs.empty()) { - invalidate_regs.push_back(LLDB_INVALID_REGNUM); - reg_info.invalidate_regs = invalidate_regs.data(); - } - - reg_num_remote = reg_info.kinds[eRegisterKindProcessPlugin] + 1; - ++reg_num_local; - reg_info.name = reg_name.AsCString(); - if (abi_sp) - abi_sp->AugmentRegisterInfo(reg_info); - dyn_reg_info.AddRegister(reg_info, reg_name, alt_name, set_name); + if (reg_info.byte_size == 0) { + Log *log( + ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS)); + LLDB_LOGF(log, + "ProcessGDBRemote::%s Skipping zero bitsize register %s", + __FUNCTION__, reg_info.name.AsCString()); + } else + registers.push_back(reg_info); return true; // Keep iterating through all "reg" elements }); @@ -4539,20 +4323,17 @@ bool ParseRegisters(XMLNode feature_node, GdbServerTargetInfo &target_info, // for nested register definition files. It returns true if it was able // to fetch and parse an xml file. bool ProcessGDBRemote::GetGDBServerRegisterInfoXMLAndProcess( - ArchSpec &arch_to_use, std::string xml_filename, uint32_t ®_num_remote, - uint32_t ®_num_local) { + ArchSpec &arch_to_use, std::string xml_filename, + std::vector<DynamicRegisterInfo::Register> ®isters) { // request the target xml file - std::string raw; - lldb_private::Status lldberr; - if (!m_gdb_comm.ReadExtFeature(ConstString("features"), - ConstString(xml_filename.c_str()), raw, - lldberr)) { + llvm::Expected<std::string> raw = m_gdb_comm.ReadExtFeature("features", xml_filename); + if (errorToBool(raw.takeError())) return false; - } XMLDocument xml_document; - if (xml_document.ParseMemory(raw.c_str(), raw.size(), xml_filename.c_str())) { + if (xml_document.ParseMemory(raw->c_str(), raw->size(), + xml_filename.c_str())) { GdbServerTargetInfo target_info; std::vector<XMLNode> feature_nodes; @@ -4581,9 +4362,9 @@ bool ProcessGDBRemote::GetGDBServerRegisterInfoXMLAndProcess( node.ForEachAttribute( [&set_id, &set_info](const llvm::StringRef &name, const llvm::StringRef &value) -> bool { + // FIXME: we're silently ignoring invalid data here if (name == "id") - set_id = StringConvert::ToUInt32(value.data(), - UINT32_MAX, 0); + llvm::to_integer(value, set_id); if (name == "name") set_info.name = ConstString(value); return true; // Keep iterating through all attributes @@ -4617,39 +4398,33 @@ bool ProcessGDBRemote::GetGDBServerRegisterInfoXMLAndProcess( } } - // If the target.xml includes an architecture entry like + // gdbserver does not implement the LLDB packets used to determine host + // or process architecture. If that is the case, attempt to use + // the <architecture/> field from target.xml, e.g.: + // // <architecture>i386:x86-64</architecture> (seen from VMWare ESXi) - // <architecture>arm</architecture> (seen from Segger JLink on unspecified arm board) - // use that if we don't have anything better. + // <architecture>arm</architecture> (seen from Segger JLink on unspecified + // arm board) if (!arch_to_use.IsValid() && !target_info.arch.empty()) { - if (target_info.arch == "i386:x86-64") { - // We don't have any information about vendor or OS. - arch_to_use.SetTriple("x86_64--"); - GetTarget().MergeArchitecture(arch_to_use); - } + // We don't have any information about vendor or OS. + arch_to_use.SetTriple(llvm::StringSwitch<std::string>(target_info.arch) + .Case("i386:x86-64", "x86_64") + .Default(target_info.arch) + + "--"); - // SEGGER J-Link jtag boards send this very-generic arch name, - // we'll need to use this if we have absolutely nothing better - // to work with or the register definitions won't be accepted. - if (target_info.arch == "arm") { - arch_to_use.SetTriple("arm--"); + if (arch_to_use.IsValid()) GetTarget().MergeArchitecture(arch_to_use); - } } if (arch_to_use.IsValid()) { - // Don't use Process::GetABI, this code gets called from DidAttach, and - // in that context we haven't set the Target's architecture yet, so the - // ABI is also potentially incorrect. - ABISP abi_to_use_sp = ABI::FindPlugin(shared_from_this(), arch_to_use); for (auto &feature_node : feature_nodes) { - ParseRegisters(feature_node, target_info, *this->m_register_info_sp, - abi_to_use_sp, reg_num_remote, reg_num_local); + ParseRegisters(feature_node, target_info, + registers); } for (const auto &include : target_info.includes) { GetGDBServerRegisterInfoXMLAndProcess(arch_to_use, include, - reg_num_remote, reg_num_local); + registers); } } } else { @@ -4658,6 +4433,46 @@ bool ProcessGDBRemote::GetGDBServerRegisterInfoXMLAndProcess( return true; } +void ProcessGDBRemote::AddRemoteRegisters( + std::vector<DynamicRegisterInfo::Register> ®isters, + const ArchSpec &arch_to_use) { + std::map<uint32_t, uint32_t> remote_to_local_map; + uint32_t remote_regnum = 0; + for (auto it : llvm::enumerate(registers)) { + DynamicRegisterInfo::Register &remote_reg_info = it.value(); + + // Assign successive remote regnums if missing. + if (remote_reg_info.regnum_remote == LLDB_INVALID_REGNUM) + remote_reg_info.regnum_remote = remote_regnum; + + // Create a mapping from remote to local regnos. + remote_to_local_map[remote_reg_info.regnum_remote] = it.index(); + + remote_regnum = remote_reg_info.regnum_remote + 1; + } + + for (DynamicRegisterInfo::Register &remote_reg_info : registers) { + auto proc_to_lldb = [&remote_to_local_map](uint32_t process_regnum) { + auto lldb_regit = remote_to_local_map.find(process_regnum); + return lldb_regit != remote_to_local_map.end() ? lldb_regit->second + : LLDB_INVALID_REGNUM; + }; + + llvm::transform(remote_reg_info.value_regs, + remote_reg_info.value_regs.begin(), proc_to_lldb); + llvm::transform(remote_reg_info.invalidate_regs, + remote_reg_info.invalidate_regs.begin(), proc_to_lldb); + } + + // Don't use Process::GetABI, this code gets called from DidAttach, and + // in that context we haven't set the Target's architecture yet, so the + // ABI is also potentially incorrect. + if (ABISP abi_sp = ABI::FindPlugin(shared_from_this(), arch_to_use)) + abi_sp->AugmentRegisterInfo(registers); + + m_register_info_sp->SetRegisterInfo(std::move(registers), arch_to_use); +} + // query the target of gdb-remote for extended target information returns // true on success (got register definitions), false on failure (did not). bool ProcessGDBRemote::GetGDBServerRegisterInfo(ArchSpec &arch_to_use) { @@ -4669,11 +4484,10 @@ bool ProcessGDBRemote::GetGDBServerRegisterInfo(ArchSpec &arch_to_use) { if (!m_gdb_comm.GetQXferFeaturesReadSupported()) return false; - uint32_t reg_num_remote = 0; - uint32_t reg_num_local = 0; + std::vector<DynamicRegisterInfo::Register> registers; if (GetGDBServerRegisterInfoXMLAndProcess(arch_to_use, "target.xml", - reg_num_remote, reg_num_local)) - this->m_register_info_sp->Finalize(arch_to_use); + registers)) + AddRemoteRegisters(registers, arch_to_use); return m_register_info_sp->GetNumRegisters() > 0; } @@ -4689,24 +4503,20 @@ llvm::Expected<LoadedModuleInfoList> ProcessGDBRemote::GetLoadedModuleList() { LoadedModuleInfoList list; GDBRemoteCommunicationClient &comm = m_gdb_comm; - bool can_use_svr4 = GetGlobalPluginProperties()->GetUseSVR4(); + bool can_use_svr4 = GetGlobalPluginProperties().GetUseSVR4(); // check that we have extended feature read support if (can_use_svr4 && comm.GetQXferLibrariesSVR4ReadSupported()) { // request the loaded library list - std::string raw; - lldb_private::Status lldberr; - - if (!comm.ReadExtFeature(ConstString("libraries-svr4"), ConstString(""), - raw, lldberr)) - return llvm::createStringError(llvm::inconvertibleErrorCode(), - "Error in libraries-svr4 packet"); + llvm::Expected<std::string> raw = comm.ReadExtFeature("libraries-svr4", ""); + if (!raw) + return raw.takeError(); // parse the xml file in memory - LLDB_LOGF(log, "parsing: %s", raw.c_str()); + LLDB_LOGF(log, "parsing: %s", raw->c_str()); XMLDocument doc; - if (!doc.ParseMemory(raw.c_str(), raw.size(), "noname.xml")) + if (!doc.ParseMemory(raw->c_str(), raw->size(), "noname.xml")) return llvm::createStringError(llvm::inconvertibleErrorCode(), "Error reading noname.xml"); @@ -4718,38 +4528,37 @@ llvm::Expected<LoadedModuleInfoList> ProcessGDBRemote::GetLoadedModuleList() { // main link map structure llvm::StringRef main_lm = root_element.GetAttributeValue("main-lm"); - if (!main_lm.empty()) { - list.m_link_map = - StringConvert::ToUInt64(main_lm.data(), LLDB_INVALID_ADDRESS, 0); - } + // FIXME: we're silently ignoring invalid data here + if (!main_lm.empty()) + llvm::to_integer(main_lm, list.m_link_map); root_element.ForEachChildElementWithName( "library", [log, &list](const XMLNode &library) -> bool { - LoadedModuleInfoList::LoadedModuleInfo module; + // FIXME: we're silently ignoring invalid data here library.ForEachAttribute( [&module](const llvm::StringRef &name, const llvm::StringRef &value) -> bool { - + uint64_t uint_value = LLDB_INVALID_ADDRESS; if (name == "name") module.set_name(value.str()); else if (name == "lm") { // the address of the link_map struct. - module.set_link_map(StringConvert::ToUInt64( - value.data(), LLDB_INVALID_ADDRESS, 0)); + llvm::to_integer(value, uint_value); + module.set_link_map(uint_value); } else if (name == "l_addr") { // the displacement as read from the field 'l_addr' of the // link_map struct. - module.set_base(StringConvert::ToUInt64( - value.data(), LLDB_INVALID_ADDRESS, 0)); + llvm::to_integer(value, uint_value); + module.set_base(uint_value); // base address is always a displacement, not an absolute // value. module.set_base_is_offset(true); } else if (name == "l_ld") { // the memory address of the libraries PT_DYNAMIC section. - module.set_dynamic(StringConvert::ToUInt64( - value.data(), LLDB_INVALID_ADDRESS, 0)); + llvm::to_integer(value, uint_value); + module.set_dynamic(uint_value); } return true; // Keep iterating over all properties of "library" @@ -4784,18 +4593,15 @@ llvm::Expected<LoadedModuleInfoList> ProcessGDBRemote::GetLoadedModuleList() { return list; } else if (comm.GetQXferLibrariesReadSupported()) { // request the loaded library list - std::string raw; - lldb_private::Status lldberr; + llvm::Expected<std::string> raw = comm.ReadExtFeature("libraries", ""); - if (!comm.ReadExtFeature(ConstString("libraries"), ConstString(""), raw, - lldberr)) - return llvm::createStringError(llvm::inconvertibleErrorCode(), - "Error in libraries packet"); + if (!raw) + return raw.takeError(); - LLDB_LOGF(log, "parsing: %s", raw.c_str()); + LLDB_LOGF(log, "parsing: %s", raw->c_str()); XMLDocument doc; - if (!doc.ParseMemory(raw.c_str(), raw.size(), "noname.xml")) + if (!doc.ParseMemory(raw->c_str(), raw->size(), "noname.xml")) return llvm::createStringError(llvm::inconvertibleErrorCode(), "Error reading noname.xml"); @@ -4804,6 +4610,7 @@ llvm::Expected<LoadedModuleInfoList> ProcessGDBRemote::GetLoadedModuleList() { return llvm::createStringError(llvm::inconvertibleErrorCode(), "Error finding library-list xml element"); + // FIXME: we're silently ignoring invalid data here root_element.ForEachChildElementWithName( "library", [log, &list](const XMLNode &library) -> bool { LoadedModuleInfoList::LoadedModuleInfo module; @@ -4817,8 +4624,9 @@ llvm::Expected<LoadedModuleInfoList> ProcessGDBRemote::GetLoadedModuleList() { const XMLNode §ion = library.FindFirstChildElementWithName("section"); llvm::StringRef address = section.GetAttributeValue("address"); - module.set_base( - StringConvert::ToUInt64(address.data(), LLDB_INVALID_ADDRESS, 0)); + uint64_t address_value = LLDB_INVALID_ADDRESS; + llvm::to_integer(address, address_value); + module.set_base(address_value); // These addresses are absolute values. module.set_base_is_offset(false); @@ -5113,6 +4921,56 @@ void ProcessGDBRemote::HandleStopReply() { BuildDynamicRegisterInfo(true); } +llvm::Expected<bool> ProcessGDBRemote::SaveCore(llvm::StringRef outfile) { + if (!m_gdb_comm.GetSaveCoreSupported()) + return false; + + StreamString packet; + packet.PutCString("qSaveCore;path-hint:"); + packet.PutStringAsRawHex8(outfile); + + StringExtractorGDBRemote response; + if (m_gdb_comm.SendPacketAndWaitForResponse(packet.GetString(), response) == + GDBRemoteCommunication::PacketResult::Success) { + // TODO: grab error message from the packet? StringExtractor seems to + // be missing a method for that + if (response.IsErrorResponse()) + return llvm::createStringError( + llvm::inconvertibleErrorCode(), + llvm::formatv("qSaveCore returned an error")); + + std::string path; + + // process the response + for (auto x : llvm::split(response.GetStringRef(), ';')) { + if (x.consume_front("core-path:")) + StringExtractor(x).GetHexByteString(path); + } + + // verify that we've gotten what we need + if (path.empty()) + return llvm::createStringError(llvm::inconvertibleErrorCode(), + "qSaveCore returned no core path"); + + // now transfer the core file + FileSpec remote_core{llvm::StringRef(path)}; + Platform &platform = *GetTarget().GetPlatform(); + Status error = platform.GetFile(remote_core, FileSpec(outfile)); + + if (platform.IsRemote()) { + // NB: we unlink the file on error too + platform.Unlink(remote_core); + if (error.Fail()) + return error.ToError(); + } + + return true; + } + + return llvm::createStringError(llvm::inconvertibleErrorCode(), + "Unable to send qSaveCore"); +} + static const char *const s_async_json_packet_prefix = "JSON-async:"; static StructuredData::ObjectSP @@ -5451,3 +5309,171 @@ CommandObject *ProcessGDBRemote::GetPluginCommandObject() { GetTarget().GetDebugger().GetCommandInterpreter()); return m_command_sp.get(); } + +void ProcessGDBRemote::DidForkSwitchSoftwareBreakpoints(bool enable) { + GetBreakpointSiteList().ForEach([this, enable](BreakpointSite *bp_site) { + if (bp_site->IsEnabled() && + (bp_site->GetType() == BreakpointSite::eSoftware || + bp_site->GetType() == BreakpointSite::eExternal)) { + m_gdb_comm.SendGDBStoppointTypePacket( + eBreakpointSoftware, enable, bp_site->GetLoadAddress(), + GetSoftwareBreakpointTrapOpcode(bp_site), GetInterruptTimeout()); + } + }); +} + +void ProcessGDBRemote::DidForkSwitchHardwareTraps(bool enable) { + if (m_gdb_comm.SupportsGDBStoppointPacket(eBreakpointHardware)) { + GetBreakpointSiteList().ForEach([this, enable](BreakpointSite *bp_site) { + if (bp_site->IsEnabled() && + bp_site->GetType() == BreakpointSite::eHardware) { + m_gdb_comm.SendGDBStoppointTypePacket( + eBreakpointHardware, enable, bp_site->GetLoadAddress(), + GetSoftwareBreakpointTrapOpcode(bp_site), GetInterruptTimeout()); + } + }); + } + + WatchpointList &wps = GetTarget().GetWatchpointList(); + size_t wp_count = wps.GetSize(); + for (size_t i = 0; i < wp_count; ++i) { + WatchpointSP wp = wps.GetByIndex(i); + if (wp->IsEnabled()) { + GDBStoppointType type = GetGDBStoppointType(wp.get()); + m_gdb_comm.SendGDBStoppointTypePacket(type, enable, wp->GetLoadAddress(), + wp->GetByteSize(), + GetInterruptTimeout()); + } + } +} + +void ProcessGDBRemote::DidFork(lldb::pid_t child_pid, lldb::tid_t child_tid) { + Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS)); + + lldb::pid_t parent_pid = m_gdb_comm.GetCurrentProcessID(); + // Any valid TID will suffice, thread-relevant actions will set a proper TID + // anyway. + lldb::tid_t parent_tid = m_thread_ids.front(); + + lldb::pid_t follow_pid, detach_pid; + lldb::tid_t follow_tid, detach_tid; + + switch (GetFollowForkMode()) { + case eFollowParent: + follow_pid = parent_pid; + follow_tid = parent_tid; + detach_pid = child_pid; + detach_tid = child_tid; + break; + case eFollowChild: + follow_pid = child_pid; + follow_tid = child_tid; + detach_pid = parent_pid; + detach_tid = parent_tid; + break; + } + + // Switch to the process that is going to be detached. + if (!m_gdb_comm.SetCurrentThread(detach_tid, detach_pid)) { + LLDB_LOG(log, "ProcessGDBRemote::DidFork() unable to set pid/tid"); + return; + } + + // Disable all software breakpoints in the forked process. + if (m_gdb_comm.SupportsGDBStoppointPacket(eBreakpointSoftware)) + DidForkSwitchSoftwareBreakpoints(false); + + // Remove hardware breakpoints / watchpoints from parent process if we're + // following child. + if (GetFollowForkMode() == eFollowChild) + DidForkSwitchHardwareTraps(false); + + // Switch to the process that is going to be followed + if (!m_gdb_comm.SetCurrentThread(follow_tid, follow_pid) || + !m_gdb_comm.SetCurrentThreadForRun(follow_tid, follow_pid)) { + LLDB_LOG(log, "ProcessGDBRemote::DidFork() unable to reset pid/tid"); + return; + } + + LLDB_LOG(log, "Detaching process {0}", detach_pid); + Status error = m_gdb_comm.Detach(false, detach_pid); + if (error.Fail()) { + LLDB_LOG(log, "ProcessGDBRemote::DidFork() detach packet send failed: {0}", + error.AsCString() ? error.AsCString() : "<unknown error>"); + return; + } + + // Hardware breakpoints/watchpoints are not inherited implicitly, + // so we need to readd them if we're following child. + if (GetFollowForkMode() == eFollowChild) + DidForkSwitchHardwareTraps(true); +} + +void ProcessGDBRemote::DidVFork(lldb::pid_t child_pid, lldb::tid_t child_tid) { + Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS)); + + assert(!m_vfork_in_progress); + m_vfork_in_progress = true; + + // Disable all software breakpoints for the duration of vfork. + if (m_gdb_comm.SupportsGDBStoppointPacket(eBreakpointSoftware)) + DidForkSwitchSoftwareBreakpoints(false); + + lldb::pid_t detach_pid; + lldb::tid_t detach_tid; + + switch (GetFollowForkMode()) { + case eFollowParent: + detach_pid = child_pid; + detach_tid = child_tid; + break; + case eFollowChild: + detach_pid = m_gdb_comm.GetCurrentProcessID(); + // Any valid TID will suffice, thread-relevant actions will set a proper TID + // anyway. + detach_tid = m_thread_ids.front(); + + // Switch to the parent process before detaching it. + if (!m_gdb_comm.SetCurrentThread(detach_tid, detach_pid)) { + LLDB_LOG(log, "ProcessGDBRemote::DidFork() unable to set pid/tid"); + return; + } + + // Remove hardware breakpoints / watchpoints from the parent process. + DidForkSwitchHardwareTraps(false); + + // Switch to the child process. + if (!m_gdb_comm.SetCurrentThread(child_tid, child_pid) || + !m_gdb_comm.SetCurrentThreadForRun(child_tid, child_pid)) { + LLDB_LOG(log, "ProcessGDBRemote::DidFork() unable to reset pid/tid"); + return; + } + break; + } + + LLDB_LOG(log, "Detaching process {0}", detach_pid); + Status error = m_gdb_comm.Detach(false, detach_pid); + if (error.Fail()) { + LLDB_LOG(log, + "ProcessGDBRemote::DidFork() detach packet send failed: {0}", + error.AsCString() ? error.AsCString() : "<unknown error>"); + return; + } +} + +void ProcessGDBRemote::DidVForkDone() { + assert(m_vfork_in_progress); + m_vfork_in_progress = false; + + // Reenable all software breakpoints that were enabled before vfork. + if (m_gdb_comm.SupportsGDBStoppointPacket(eBreakpointSoftware)) + DidForkSwitchSoftwareBreakpoints(true); +} + +void ProcessGDBRemote::DidExec() { + // If we are following children, vfork is finished by exec (rather than + // vforkdone that is submitted for parent). + if (GetFollowForkMode() == eFollowChild) + m_vfork_in_progress = false; + Process::DidExec(); +} diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h b/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h index fe04cdddd0f5..8134bc6b530d 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h +++ b/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h @@ -19,6 +19,7 @@ #include "lldb/Core/ModuleSpec.h" #include "lldb/Core/ThreadSafeValue.h" #include "lldb/Host/HostThread.h" +#include "lldb/Target/DynamicRegisterInfo.h" #include "lldb/Target/Process.h" #include "lldb/Target/Thread.h" #include "lldb/Utility/ArchSpec.h" @@ -64,9 +65,9 @@ public: static void Terminate(); - static ConstString GetPluginNameStatic(); + static llvm::StringRef GetPluginNameStatic() { return "gdb-remote"; } - static const char *GetPluginDescriptionStatic(); + static llvm::StringRef GetPluginDescriptionStatic(); static std::chrono::seconds GetPacketTimeout(); @@ -102,9 +103,7 @@ public: void DidAttach(ArchSpec &process_arch) override; // PluginInterface protocol - ConstString GetPluginName() override; - - uint32_t GetPluginVersion() override; + llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); } // Process Control Status WillResume() override; @@ -145,9 +144,6 @@ public: lldb::addr_t DoAllocateMemory(size_t size, uint32_t permissions, Status &error) override; - Status GetMemoryRegionInfo(lldb::addr_t load_addr, - MemoryRegionInfo ®ion_info) override; - Status DoDeallocateMemory(lldb::addr_t ptr) override; // Process STDIO @@ -230,6 +226,13 @@ public: std::string HarmonizeThreadIdsForProfileData( StringExtractorGDBRemote &inputStringExtractor); + void DidFork(lldb::pid_t child_pid, lldb::tid_t child_tid) override; + void DidVFork(lldb::pid_t child_pid, lldb::tid_t child_tid) override; + void DidVForkDone() override; + void DidExec() override; + + llvm::Expected<bool> SaveCore(llvm::StringRef outfile) override; + protected: friend class ThreadGDBRemote; friend class GDBRemoteCommunicationClient; @@ -247,11 +250,10 @@ protected: GDBRemoteCommunicationClient m_gdb_comm; GDBRemoteCommunicationReplayServer m_gdb_replay_server; std::atomic<lldb::pid_t> m_debugserver_pid; - std::vector<StringExtractorGDBRemote> m_stop_packet_stack; // The stop packet - // stack replaces - // the last stop - // packet variable + + llvm::Optional<StringExtractorGDBRemote> m_last_stop_packet; std::recursive_mutex m_last_stop_packet_mutex; + GDBRemoteDynamicRegisterInfoSP m_register_info_sp; Broadcaster m_async_broadcaster; lldb::ListenerSP m_async_listener_sp; @@ -293,6 +295,8 @@ protected: using FlashRange = FlashRangeVector::Entry; FlashRangeVector m_erased_flash_ranges; + bool m_vfork_in_progress; + // Accessors bool IsRunning(lldb::StateType state) { return state == lldb::eStateRunning || IsStepping(state); @@ -335,7 +339,7 @@ protected: bool CalculateThreadStopInfo(ThreadGDBRemote *thread); - size_t UpdateThreadPCsFromStopReplyThreadsValue(std::string &value); + size_t UpdateThreadPCsFromStopReplyThreadsValue(llvm::StringRef value); size_t UpdateThreadIDsFromStopReplyThreadsValue(llvm::StringRef value); @@ -387,11 +391,14 @@ protected: DynamicLoader *GetDynamicLoader() override; - bool GetGDBServerRegisterInfoXMLAndProcess(ArchSpec &arch_to_use, - std::string xml_filename, - uint32_t &cur_reg_remote, - uint32_t &cur_reg_local); + bool GetGDBServerRegisterInfoXMLAndProcess( + ArchSpec &arch_to_use, std::string xml_filename, + std::vector<DynamicRegisterInfo::Register> ®isters); + // Convert DynamicRegisterInfo::Registers into RegisterInfos and add + // to the dynamic register list. + void AddRemoteRegisters(std::vector<DynamicRegisterInfo::Register> ®isters, + const ArchSpec &arch_to_use); // Query remote GDBServer for register information bool GetGDBServerRegisterInfo(ArchSpec &arch); @@ -414,6 +421,9 @@ protected: Status DoWriteMemoryTags(lldb::addr_t addr, size_t len, int32_t type, const std::vector<uint8_t> &tags) override; + Status DoGetMemoryRegionInfo(lldb::addr_t load_addr, + MemoryRegionInfo ®ion_info) override; + private: // For ProcessGDBRemote only std::string m_partial_profile_data; @@ -459,6 +469,10 @@ private: ProcessGDBRemote(const ProcessGDBRemote &) = delete; const ProcessGDBRemote &operator=(const ProcessGDBRemote &) = delete; + + // fork helpers + void DidForkSwitchSoftwareBreakpoints(bool enable); + void DidForkSwitchHardwareTraps(bool enable); }; } // namespace process_gdb_remote diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/minidump/ProcessMinidump.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/minidump/ProcessMinidump.cpp index 385557422758..736cfa070088 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/minidump/ProcessMinidump.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Process/minidump/ProcessMinidump.cpp @@ -63,8 +63,9 @@ public: static ConstString GetStaticPluginName() { return ConstString("placeholder"); } - ConstString GetPluginName() override { return GetStaticPluginName(); } - uint32_t GetPluginVersion() override { return 1; } + llvm::StringRef GetPluginName() override { + return GetStaticPluginName().GetStringRef(); + } bool ParseHeader() override { return true; } Type CalculateType() override { return eTypeUnknown; } Strata CalculateStrata() override { return eStrataUnknown; } @@ -189,12 +190,7 @@ void HashElfTextSection(ModuleSP module_sp, std::vector<uint8_t> &breakpad_uuid, } // namespace -ConstString ProcessMinidump::GetPluginNameStatic() { - static ConstString g_name("minidump"); - return g_name; -} - -const char *ProcessMinidump::GetPluginDescriptionStatic() { +llvm::StringRef ProcessMinidump::GetPluginDescriptionStatic() { return "Minidump plug-in."; } @@ -305,10 +301,6 @@ Status ProcessMinidump::DoLoadCore() { return error; } -ConstString ProcessMinidump::GetPluginName() { return GetPluginNameStatic(); } - -uint32_t ProcessMinidump::GetPluginVersion() { return 1; } - Status ProcessMinidump::DoDestroy() { return Status(); } void ProcessMinidump::RefreshStateAfterStop() { @@ -447,8 +439,8 @@ void ProcessMinidump::BuildMemoryRegions() { llvm::sort(*m_memory_regions); } -Status ProcessMinidump::GetMemoryRegionInfo(lldb::addr_t load_addr, - MemoryRegionInfo ®ion) { +Status ProcessMinidump::DoGetMemoryRegionInfo(lldb::addr_t load_addr, + MemoryRegionInfo ®ion) { BuildMemoryRegions(); region = MinidumpParser::GetMemoryRegionInfo(*m_memory_regions, load_addr); return Status(); @@ -584,8 +576,9 @@ void ProcessMinidump::ReadModuleList() { // we don't then we will end up setting the load address of a different // PlaceholderObjectFile and an assertion will fire. auto *objfile = module_sp->GetObjectFile(); - if (objfile && objfile->GetPluginName() == - PlaceholderObjectFile::GetStaticPluginName()) { + if (objfile && + objfile->GetPluginName() == + PlaceholderObjectFile::GetStaticPluginName().GetStringRef()) { if (((PlaceholderObjectFile *)objfile)->GetBaseImageAddress() != load_addr) module_sp.reset(); diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/minidump/ProcessMinidump.h b/contrib/llvm-project/lldb/source/Plugins/Process/minidump/ProcessMinidump.h index 27b0da0047a5..5360269199cd 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/minidump/ProcessMinidump.h +++ b/contrib/llvm-project/lldb/source/Plugins/Process/minidump/ProcessMinidump.h @@ -37,9 +37,9 @@ public: static void Terminate(); - static ConstString GetPluginNameStatic(); + static llvm::StringRef GetPluginNameStatic() { return "minidump"; } - static const char *GetPluginDescriptionStatic(); + static llvm::StringRef GetPluginDescriptionStatic(); ProcessMinidump(lldb::TargetSP target_sp, lldb::ListenerSP listener_sp, const FileSpec &core_file, lldb::DataBufferSP code_data); @@ -55,9 +55,7 @@ public: DynamicLoader *GetDynamicLoader() override { return nullptr; } - ConstString GetPluginName() override; - - uint32_t GetPluginVersion() override; + llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); } SystemRuntime *GetSystemRuntime() override { return nullptr; } @@ -77,9 +75,6 @@ public: ArchSpec GetArchitecture(); - Status GetMemoryRegionInfo(lldb::addr_t load_addr, - MemoryRegionInfo &range_info) override; - Status GetMemoryRegions( lldb_private::MemoryRegionInfos ®ion_list) override; @@ -87,9 +82,8 @@ public: Status WillResume() override { Status error; - error.SetErrorStringWithFormat( - "error: %s does not support resuming processes", - GetPluginName().GetCString()); + error.SetErrorStringWithFormatv( + "error: {0} does not support resuming processes", GetPluginName()); return error; } @@ -101,6 +95,9 @@ protected: bool DoUpdateThreadList(ThreadList &old_thread_list, ThreadList &new_thread_list) override; + Status DoGetMemoryRegionInfo(lldb::addr_t load_addr, + MemoryRegionInfo &range_info) override; + void ReadModuleList(); lldb::ModuleSP GetOrCreateModule(lldb_private::UUID minidump_uuid, diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/minidump/RegisterContextMinidump_ARM.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/minidump/RegisterContextMinidump_ARM.cpp index 7e309e8322a8..7184dbacb08d 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/minidump/RegisterContextMinidump_ARM.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Process/minidump/RegisterContextMinidump_ARM.cpp @@ -30,36 +30,35 @@ using namespace minidump; #define DEF_R(i) \ { \ "r" #i, nullptr, 4, OFFSET(r) + i * 4, eEncodingUint, eFormatHex, \ - {ehframe_r##i, dwarf_r##i, INV, INV, reg_r##i}, \ - nullptr, nullptr, nullptr, 0 \ + {ehframe_r##i, dwarf_r##i, INV, INV, reg_r##i}, nullptr, nullptr, \ } #define DEF_R_ARG(i, n) \ { \ "r" #i, "arg" #n, 4, OFFSET(r) + i * 4, eEncodingUint, eFormatHex, \ - {ehframe_r##i, dwarf_r##i, LLDB_REGNUM_GENERIC_ARG1 + i, INV, reg_r##i}, \ - nullptr, nullptr, nullptr, 0 \ + {ehframe_r##i, dwarf_r##i, LLDB_REGNUM_GENERIC_ARG1 + i, INV, \ + reg_r##i}, \ + nullptr, nullptr, \ } #define DEF_D(i) \ { \ "d" #i, nullptr, 8, OFFSET(d) + i * 8, eEncodingVector, \ eFormatVectorOfUInt8, {dwarf_d##i, dwarf_d##i, INV, INV, reg_d##i}, \ - nullptr, nullptr, nullptr, 0 \ + nullptr, nullptr, \ } #define DEF_S(i) \ { \ "s" #i, nullptr, 4, OFFSET(s) + i * 4, eEncodingIEEE754, eFormatFloat, \ - {dwarf_s##i, dwarf_s##i, INV, INV, reg_s##i}, \ - nullptr, nullptr, nullptr, 0 \ + {dwarf_s##i, dwarf_s##i, INV, INV, reg_s##i}, nullptr, nullptr, \ } #define DEF_Q(i) \ { \ "q" #i, nullptr, 16, OFFSET(q) + i * 16, eEncodingVector, \ eFormatVectorOfUInt8, {dwarf_q##i, dwarf_q##i, INV, INV, reg_q##i}, \ - nullptr, nullptr, nullptr, 0 \ + nullptr, nullptr, \ } // Zero based LLDB register numbers for this register context @@ -177,8 +176,7 @@ static RegisterInfo g_reg_info_apple_fp = { {ehframe_r7, dwarf_r7, LLDB_REGNUM_GENERIC_FP, INV, reg_r7}, nullptr, nullptr, - nullptr, - 0}; +}; static RegisterInfo g_reg_info_fp = { "fp", @@ -190,8 +188,7 @@ static RegisterInfo g_reg_info_fp = { {ehframe_r11, dwarf_r11, LLDB_REGNUM_GENERIC_FP, INV, reg_r11}, nullptr, nullptr, - nullptr, - 0}; +}; // Register info definitions for this register context static RegisterInfo g_reg_infos[] = { @@ -217,8 +214,7 @@ static RegisterInfo g_reg_infos[] = { {ehframe_sp, dwarf_sp, LLDB_REGNUM_GENERIC_SP, INV, reg_sp}, nullptr, nullptr, - nullptr, - 0}, + }, {"lr", "r14", 4, @@ -228,8 +224,7 @@ static RegisterInfo g_reg_infos[] = { {ehframe_lr, dwarf_lr, LLDB_REGNUM_GENERIC_RA, INV, reg_lr}, nullptr, nullptr, - nullptr, - 0}, + }, {"pc", "r15", 4, @@ -239,8 +234,7 @@ static RegisterInfo g_reg_infos[] = { {ehframe_pc, dwarf_pc, LLDB_REGNUM_GENERIC_PC, INV, reg_pc}, nullptr, nullptr, - nullptr, - 0}, + }, {"cpsr", "psr", 4, @@ -250,8 +244,7 @@ static RegisterInfo g_reg_infos[] = { {ehframe_cpsr, dwarf_cpsr, LLDB_REGNUM_GENERIC_FLAGS, INV, reg_cpsr}, nullptr, nullptr, - nullptr, - 0}, + }, {"fpscr", nullptr, 8, @@ -261,8 +254,7 @@ static RegisterInfo g_reg_infos[] = { {INV, INV, INV, INV, reg_fpscr}, nullptr, nullptr, - nullptr, - 0}, + }, DEF_D(0), DEF_D(1), DEF_D(2), diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/minidump/RegisterContextMinidump_ARM64.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/minidump/RegisterContextMinidump_ARM64.cpp index e2b7c0e362a7..e606ec9c3b64 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/minidump/RegisterContextMinidump_ARM64.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Process/minidump/RegisterContextMinidump_ARM64.cpp @@ -29,48 +29,48 @@ using namespace minidump; { \ "x" #i, nullptr, 8, OFFSET(x) + i * 8, eEncodingUint, eFormatHex, \ {arm64_dwarf::x##i, arm64_dwarf::x##i, INV, INV, reg_x##i}, \ - nullptr, nullptr, nullptr, 0 \ + nullptr, nullptr, \ } #define DEF_W(i) \ { \ "w" #i, nullptr, 4, OFFSET(x) + i * 8, eEncodingUint, eFormatHex, \ - {INV, INV, INV, INV, reg_w##i}, nullptr, nullptr, nullptr, 0 \ + {INV, INV, INV, INV, reg_w##i}, nullptr, nullptr, \ } #define DEF_X_ARG(i, n) \ { \ "x" #i, "arg" #n, 8, OFFSET(x) + i * 8, eEncodingUint, eFormatHex, \ {arm64_dwarf::x##i, arm64_dwarf::x##i, LLDB_REGNUM_GENERIC_ARG1 + i, \ - INV, reg_x##i}, nullptr, nullptr, nullptr, 0 \ + INV, reg_x##i}, nullptr, nullptr, \ } #define DEF_V(i) \ { \ "v" #i, nullptr, 16, OFFSET(v) + i * 16, eEncodingVector, \ eFormatVectorOfUInt8, {arm64_dwarf::v##i, arm64_dwarf::v##i, INV, INV, \ - reg_v##i}, nullptr, nullptr, nullptr, 0 \ + reg_v##i}, nullptr, nullptr, \ } #define DEF_D(i) \ { \ "d" #i, nullptr, 8, OFFSET(v) + i * 16, eEncodingVector, \ eFormatVectorOfUInt8, {INV, INV, INV, INV, reg_d##i}, nullptr, \ - nullptr, nullptr, 0 \ + nullptr, \ } #define DEF_S(i) \ { \ "s" #i, nullptr, 4, OFFSET(v) + i * 16, eEncodingVector, \ eFormatVectorOfUInt8, {INV, INV, INV, INV, reg_s##i}, nullptr, \ - nullptr, nullptr, 0 \ + nullptr, \ } #define DEF_H(i) \ { \ "h" #i, nullptr, 2, OFFSET(v) + i * 16, eEncodingVector, \ eFormatVectorOfUInt8, {INV, INV, INV, INV, reg_h##i}, nullptr, \ - nullptr, nullptr, 0 \ + nullptr, \ } // Zero based LLDB register numbers for this register context @@ -316,8 +316,7 @@ static RegisterInfo g_reg_infos[] = { {arm64_dwarf::x29, arm64_dwarf::x29, LLDB_REGNUM_GENERIC_FP, INV, reg_fp}, nullptr, nullptr, - nullptr, - 0}, + }, {"lr", "x30", 8, @@ -327,8 +326,7 @@ static RegisterInfo g_reg_infos[] = { {arm64_dwarf::x30, arm64_dwarf::x30, LLDB_REGNUM_GENERIC_RA, INV, reg_lr}, nullptr, nullptr, - nullptr, - 0}, + }, {"sp", "x31", 8, @@ -338,8 +336,7 @@ static RegisterInfo g_reg_infos[] = { {arm64_dwarf::x31, arm64_dwarf::x31, LLDB_REGNUM_GENERIC_SP, INV, reg_sp}, nullptr, nullptr, - nullptr, - 0}, + }, {"pc", nullptr, 8, @@ -349,8 +346,7 @@ static RegisterInfo g_reg_infos[] = { {arm64_dwarf::pc, arm64_dwarf::pc, LLDB_REGNUM_GENERIC_PC, INV, reg_pc}, nullptr, nullptr, - nullptr, - 0}, + }, // w0 - w31 DEF_W(0), DEF_W(1), @@ -393,8 +389,7 @@ static RegisterInfo g_reg_infos[] = { {INV, arm64_dwarf::cpsr, LLDB_REGNUM_GENERIC_FLAGS, INV, reg_cpsr}, nullptr, nullptr, - nullptr, - 0}, + }, {"fpsr", nullptr, 4, @@ -404,8 +399,7 @@ static RegisterInfo g_reg_infos[] = { {INV, INV, INV, INV, reg_fpsr}, nullptr, nullptr, - nullptr, - 0}, + }, {"fpcr", nullptr, 4, @@ -415,8 +409,7 @@ static RegisterInfo g_reg_infos[] = { {INV, INV, INV, INV, reg_fpcr}, nullptr, nullptr, - nullptr, - 0}, + }, // v0 - v31 DEF_V(0), DEF_V(1), diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/scripted/ScriptedProcess.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/scripted/ScriptedProcess.cpp index 09e9375b6f66..15d3d43d9993 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/scripted/ScriptedProcess.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Process/scripted/ScriptedProcess.cpp @@ -20,9 +20,6 @@ #include "lldb/Interpreter/ScriptInterpreter.h" #include "lldb/Target/MemoryRegionInfo.h" #include "lldb/Target/RegisterContext.h" - -#include "lldb/Utility/Log.h" -#include "lldb/Utility/Logging.h" #include "lldb/Utility/State.h" #include <mutex> @@ -32,12 +29,7 @@ LLDB_PLUGIN_DEFINE(ScriptedProcess) using namespace lldb; using namespace lldb_private; -ConstString ScriptedProcess::GetPluginNameStatic() { - static ConstString g_name("ScriptedProcess"); - return g_name; -} - -const char *ScriptedProcess::GetPluginDescriptionStatic() { +llvm::StringRef ScriptedProcess::GetPluginDescriptionStatic() { return "Scripted Process plug-in."; } @@ -109,9 +101,11 @@ ScriptedProcess::ScriptedProcess( return; } - StructuredData::ObjectSP object_sp = GetInterface().CreatePluginObject( - m_scripted_process_info.GetClassName().c_str(), target_sp, - m_scripted_process_info.GetDictionarySP()); + ExecutionContext exe_ctx(target_sp, /*get_process=*/false); + + StructuredData::GenericSP object_sp = GetInterface().CreatePluginObject( + m_scripted_process_info.GetClassName().c_str(), exe_ctx, + m_scripted_process_info.GetArgsSP()); if (!object_sp || !object_sp->IsValid()) { error.SetErrorStringWithFormat("ScriptedProcess::%s () - ERROR: %s", @@ -145,10 +139,6 @@ void ScriptedProcess::Terminate() { PluginManager::UnregisterPlugin(ScriptedProcess::CreateInstance); } -ConstString ScriptedProcess::GetPluginName() { return GetPluginNameStatic(); } - -uint32_t ScriptedProcess::GetPluginVersion() { return 1; } - Status ScriptedProcess::DoLoadCore() { ProcessLaunchInfo launch_info = GetTarget().GetProcessLaunchInfo(); @@ -234,26 +224,22 @@ bool ScriptedProcess::IsAlive() { size_t ScriptedProcess::DoReadMemory(lldb::addr_t addr, void *buf, size_t size, Status &error) { - - auto error_with_message = [&error](llvm::StringRef message) { - error.SetErrorString(message); - return 0; - }; - if (!m_interpreter) - return error_with_message("No interpreter."); + return GetInterface().ErrorWithMessage<size_t>(LLVM_PRETTY_FUNCTION, + "No interpreter.", error); lldb::DataExtractorSP data_extractor_sp = GetInterface().ReadMemoryAtAddress(addr, size, error); - if (!data_extractor_sp || error.Fail()) + if (!data_extractor_sp || !data_extractor_sp->GetByteSize() || error.Fail()) return 0; offset_t bytes_copied = data_extractor_sp->CopyByteOrderedData( 0, data_extractor_sp->GetByteSize(), buf, size, GetByteOrder()); if (!bytes_copied || bytes_copied == LLDB_INVALID_OFFSET) - return error_with_message("Failed to copy read memory to buffer."); + return GetInterface().ErrorWithMessage<size_t>( + LLVM_PRETTY_FUNCTION, "Failed to copy read memory to buffer.", error); return size; } @@ -262,26 +248,36 @@ ArchSpec ScriptedProcess::GetArchitecture() { return GetTarget().GetArchitecture(); } -Status ScriptedProcess::GetMemoryRegionInfo(lldb::addr_t load_addr, - MemoryRegionInfo ®ion) { - // TODO: Implement - return Status(); +Status ScriptedProcess::DoGetMemoryRegionInfo(lldb::addr_t load_addr, + MemoryRegionInfo ®ion) { + CheckInterpreterAndScriptObject(); + + Status error; + if (auto region_or_err = + GetInterface().GetMemoryRegionContainingAddress(load_addr, error)) + region = *region_or_err; + + return error; } Status ScriptedProcess::GetMemoryRegions(MemoryRegionInfos ®ion_list) { CheckInterpreterAndScriptObject(); + Status error; lldb::addr_t address = 0; - lldb::MemoryRegionInfoSP mem_region_sp = nullptr; - while ((mem_region_sp = - GetInterface().GetMemoryRegionContainingAddress(address))) { - auto range = mem_region_sp->GetRange(); + while (auto region_or_err = + GetInterface().GetMemoryRegionContainingAddress(address, error)) { + if (error.Fail()) + break; + + MemoryRegionInfo &mem_region = *region_or_err; + auto range = mem_region.GetRange(); address += range.GetRangeBase() + range.GetByteSize(); - region_list.push_back(*mem_region_sp.get()); + region_list.push_back(mem_region); } - return {}; + return error; } void ScriptedProcess::Clear() { Process::m_thread_list.Clear(); } @@ -292,9 +288,40 @@ bool ScriptedProcess::DoUpdateThreadList(ThreadList &old_thread_list, // This is supposed to get the current set of threads, if any of them are in // old_thread_list then they get copied to new_thread_list, and then any // actually new threads will get added to new_thread_list. + + CheckInterpreterAndScriptObject(); + m_thread_plans.ClearThreadCache(); + + Status error; + ScriptLanguage language = m_interpreter->GetLanguage(); + + if (language != eScriptLanguagePython) + return GetInterface().ErrorWithMessage<bool>( + LLVM_PRETTY_FUNCTION, + llvm::Twine("ScriptInterpreter language (" + + llvm::Twine(m_interpreter->LanguageToString(language)) + + llvm::Twine(") not supported.")) + .str(), + error); + + lldb::ThreadSP thread_sp; + thread_sp = std::make_shared<ScriptedThread>(*this, error); + + if (!thread_sp || error.Fail()) + return GetInterface().ErrorWithMessage<bool>(LLVM_PRETTY_FUNCTION, + error.AsCString(), error); + + new_thread_list.AddThread(thread_sp); + return new_thread_list.GetSize(false) > 0; } +void ScriptedProcess::RefreshStateAfterStop() { + // Let all threads recover from stopping and do any clean up based on the + // previous thread state (if any). + m_thread_list.RefreshStateAfterStop(); +} + bool ScriptedProcess::GetProcessInfo(ProcessInstanceInfo &info) { info.Clear(); info.SetProcessID(GetID()); diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/scripted/ScriptedProcess.h b/contrib/llvm-project/lldb/source/Plugins/Process/scripted/ScriptedProcess.h index 98c1a1ca4fe9..c8355f35548a 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/scripted/ScriptedProcess.h +++ b/contrib/llvm-project/lldb/source/Plugins/Process/scripted/ScriptedProcess.h @@ -13,6 +13,8 @@ #include "lldb/Utility/ConstString.h" #include "lldb/Utility/Status.h" +#include "ScriptedThread.h" + #include <mutex> namespace lldb_private { @@ -23,17 +25,15 @@ protected: public: ScriptedProcessInfo(const ProcessLaunchInfo &launch_info) { m_class_name = launch_info.GetScriptedProcessClassName(); - m_dictionary_sp = launch_info.GetScriptedProcessDictionarySP(); + m_args_sp = launch_info.GetScriptedProcessDictionarySP(); } std::string GetClassName() const { return m_class_name; } - StructuredData::DictionarySP GetDictionarySP() const { - return m_dictionary_sp; - } + StructuredData::DictionarySP GetArgsSP() const { return m_args_sp; } private: std::string m_class_name; - StructuredData::DictionarySP m_dictionary_sp; + StructuredData::DictionarySP m_args_sp; }; public: @@ -46,9 +46,9 @@ public: static void Terminate(); - static ConstString GetPluginNameStatic(); + static llvm::StringRef GetPluginNameStatic() { return "ScriptedProcess"; } - static const char *GetPluginDescriptionStatic(); + static llvm::StringRef GetPluginDescriptionStatic(); ScriptedProcess(lldb::TargetSP target_sp, lldb::ListenerSP listener_sp, const ScriptedProcess::ScriptedProcessInfo &launch_info, @@ -61,9 +61,7 @@ public: DynamicLoader *GetDynamicLoader() override { return nullptr; } - ConstString GetPluginName() override; - - uint32_t GetPluginVersion() override; + llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); } SystemRuntime *GetSystemRuntime() override { return nullptr; } @@ -77,7 +75,7 @@ public: Status DoDestroy() override; - void RefreshStateAfterStop() override{}; + void RefreshStateAfterStop() override; bool IsAlive() override; @@ -86,9 +84,6 @@ public: ArchSpec GetArchitecture(); - Status GetMemoryRegionInfo(lldb::addr_t load_addr, - MemoryRegionInfo &range_info) override; - Status GetMemoryRegions(lldb_private::MemoryRegionInfos ®ion_list) override; @@ -102,7 +97,12 @@ protected: bool DoUpdateThreadList(ThreadList &old_thread_list, ThreadList &new_thread_list) override; + Status DoGetMemoryRegionInfo(lldb::addr_t load_addr, + MemoryRegionInfo &range_info) override; + private: + friend class ScriptedThread; + void CheckInterpreterAndScriptObject() const; ScriptedProcessInterface &GetInterface() const; static bool IsScriptLanguageSupported(lldb::ScriptLanguage language); diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/scripted/ScriptedThread.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/scripted/ScriptedThread.cpp new file mode 100644 index 000000000000..1adbd4e7799d --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Process/scripted/ScriptedThread.cpp @@ -0,0 +1,211 @@ +//===-- ScriptedThread.cpp ------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "ScriptedThread.h" + +#include "Plugins/Process/Utility/RegisterContextThreadMemory.h" +#include "lldb/Target/OperatingSystem.h" +#include "lldb/Target/Process.h" +#include "lldb/Target/RegisterContext.h" +#include "lldb/Target/StopInfo.h" +#include "lldb/Target/Unwind.h" +#include "lldb/Utility/DataBufferHeap.h" +#include "lldb/Utility/Log.h" +#include "lldb/Utility/Logging.h" + +#include <memory> + +using namespace lldb; +using namespace lldb_private; + +void ScriptedThread::CheckInterpreterAndScriptObject() const { + lldbassert(m_script_object_sp && "Invalid Script Object."); + lldbassert(GetInterface() && "Invalid Scripted Thread Interface."); +} + +ScriptedThread::ScriptedThread(ScriptedProcess &process, Status &error) + : Thread(process, LLDB_INVALID_THREAD_ID), m_scripted_process(process) { + if (!process.IsValid()) { + error.SetErrorString("Invalid scripted process"); + return; + } + + process.CheckInterpreterAndScriptObject(); + + auto scripted_thread_interface = GetInterface(); + if (!scripted_thread_interface) { + error.SetErrorString("Failed to get scripted thread interface."); + return; + } + + llvm::Optional<std::string> class_name = + process.GetInterface().GetScriptedThreadPluginName(); + if (!class_name || class_name->empty()) { + error.SetErrorString("Failed to get scripted thread class name."); + return; + } + + ExecutionContext exe_ctx(process); + + StructuredData::GenericSP object_sp = + scripted_thread_interface->CreatePluginObject( + class_name->c_str(), exe_ctx, + process.m_scripted_process_info.GetArgsSP()); + if (!object_sp || !object_sp->IsValid()) { + error.SetErrorString("Failed to create valid script object"); + return; + } + + m_script_object_sp = object_sp; + + SetID(scripted_thread_interface->GetThreadID()); +} + +ScriptedThread::~ScriptedThread() { DestroyThread(); } + +const char *ScriptedThread::GetName() { + CheckInterpreterAndScriptObject(); + llvm::Optional<std::string> thread_name = GetInterface()->GetName(); + if (!thread_name) + return nullptr; + return ConstString(thread_name->c_str()).AsCString(); +} + +const char *ScriptedThread::GetQueueName() { + CheckInterpreterAndScriptObject(); + llvm::Optional<std::string> queue_name = GetInterface()->GetQueue(); + if (!queue_name) + return nullptr; + return ConstString(queue_name->c_str()).AsCString(); +} + +void ScriptedThread::WillResume(StateType resume_state) {} + +void ScriptedThread::ClearStackFrames() { Thread::ClearStackFrames(); } + +RegisterContextSP ScriptedThread::GetRegisterContext() { + if (!m_reg_context_sp) + m_reg_context_sp = CreateRegisterContextForFrame(nullptr); + return m_reg_context_sp; +} + +RegisterContextSP +ScriptedThread::CreateRegisterContextForFrame(StackFrame *frame) { + const uint32_t concrete_frame_idx = + frame ? frame->GetConcreteFrameIndex() : 0; + + if (concrete_frame_idx) + return GetUnwinder().CreateRegisterContextForFrame(frame); + + lldb::RegisterContextSP reg_ctx_sp; + Status error; + + llvm::Optional<std::string> reg_data = GetInterface()->GetRegisterContext(); + if (!reg_data) + return GetInterface()->ErrorWithMessage<lldb::RegisterContextSP>( + LLVM_PRETTY_FUNCTION, "Failed to get scripted thread registers data.", + error, LIBLLDB_LOG_THREAD); + + DataBufferSP data_sp( + std::make_shared<DataBufferHeap>(reg_data->c_str(), reg_data->size())); + + if (!data_sp->GetByteSize()) + return GetInterface()->ErrorWithMessage<lldb::RegisterContextSP>( + LLVM_PRETTY_FUNCTION, "Failed to copy raw registers data.", error, + LIBLLDB_LOG_THREAD); + + std::shared_ptr<RegisterContextMemory> reg_ctx_memory = + std::make_shared<RegisterContextMemory>( + *this, 0, *GetDynamicRegisterInfo(), LLDB_INVALID_ADDRESS); + if (!reg_ctx_memory) + return GetInterface()->ErrorWithMessage<lldb::RegisterContextSP>( + LLVM_PRETTY_FUNCTION, "Failed to create a register context.", error, + LIBLLDB_LOG_THREAD); + + reg_ctx_memory->SetAllRegisterData(data_sp); + m_reg_context_sp = reg_ctx_memory; + + return m_reg_context_sp; +} + +bool ScriptedThread::CalculateStopInfo() { + StructuredData::DictionarySP dict_sp = GetInterface()->GetStopReason(); + + Status error; + lldb::StopInfoSP stop_info_sp; + lldb::StopReason stop_reason_type; + + if (!dict_sp->GetValueForKeyAsInteger("type", stop_reason_type)) + return GetInterface()->ErrorWithMessage<bool>( + LLVM_PRETTY_FUNCTION, + "Couldn't find value for key 'type' in stop reason dictionary.", error, + LIBLLDB_LOG_THREAD); + + StructuredData::Dictionary *data_dict; + if (!dict_sp->GetValueForKeyAsDictionary("data", data_dict)) + return GetInterface()->ErrorWithMessage<bool>( + LLVM_PRETTY_FUNCTION, + "Couldn't find value for key 'type' in stop reason dictionary.", error, + LIBLLDB_LOG_THREAD); + + switch (stop_reason_type) { + case lldb::eStopReasonNone: + break; + case lldb::eStopReasonBreakpoint: { + lldb::break_id_t break_id; + data_dict->GetValueForKeyAsInteger("break_id", break_id, + LLDB_INVALID_BREAK_ID); + stop_info_sp = + StopInfo::CreateStopReasonWithBreakpointSiteID(*this, break_id); + } break; + case lldb::eStopReasonSignal: { + int signal; + llvm::StringRef description; + data_dict->GetValueForKeyAsInteger("signal", signal, + LLDB_INVALID_SIGNAL_NUMBER); + data_dict->GetValueForKeyAsString("desc", description); + stop_info_sp = + StopInfo::CreateStopReasonWithSignal(*this, signal, description.data()); + } break; + default: + return GetInterface()->ErrorWithMessage<bool>( + LLVM_PRETTY_FUNCTION, + llvm::Twine("Unsupported stop reason type (" + + llvm::Twine(stop_reason_type) + llvm::Twine(").")) + .str(), + error, LIBLLDB_LOG_THREAD); + } + + SetStopInfo(stop_info_sp); + return true; +} + +void ScriptedThread::RefreshStateAfterStop() { + GetRegisterContext()->InvalidateIfNeeded(/*force=*/false); +} + +lldb::ScriptedThreadInterfaceSP ScriptedThread::GetInterface() const { + return m_scripted_process.GetInterface().GetScriptedThreadInterface(); +} + +std::shared_ptr<DynamicRegisterInfo> ScriptedThread::GetDynamicRegisterInfo() { + CheckInterpreterAndScriptObject(); + + if (!m_register_info_sp) { + StructuredData::DictionarySP reg_info = GetInterface()->GetRegisterInfo(); + if (!reg_info) + return nullptr; + + m_register_info_sp = std::make_shared<DynamicRegisterInfo>( + *reg_info, m_scripted_process.GetTarget().GetArchitecture()); + assert(m_register_info_sp->GetNumRegisters() > 0); + assert(m_register_info_sp->GetNumRegisterSets() > 0); + } + + return m_register_info_sp; +} diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/scripted/ScriptedThread.h b/contrib/llvm-project/lldb/source/Plugins/Process/scripted/ScriptedThread.h new file mode 100644 index 000000000000..cdcd543702a4 --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Process/scripted/ScriptedThread.h @@ -0,0 +1,68 @@ +//===-- ScriptedThread.h ----------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_SOURCE_PLUGINS_SCRIPTED_THREAD_H +#define LLDB_SOURCE_PLUGINS_SCRIPTED_THREAD_H + +#include <string> + +#include "ScriptedProcess.h" + +#include "Plugins/Process/Utility/RegisterContextMemory.h" +#include "lldb/Interpreter/ScriptInterpreter.h" +#include "lldb/Target//DynamicRegisterInfo.h" +#include "lldb/Target/Thread.h" + +namespace lldb_private { +class ScriptedProcess; +} + +namespace lldb_private { + +class ScriptedThread : public lldb_private::Thread { +public: + ScriptedThread(ScriptedProcess &process, Status &error); + + ~ScriptedThread() override; + + lldb::RegisterContextSP GetRegisterContext() override; + + lldb::RegisterContextSP + CreateRegisterContextForFrame(lldb_private::StackFrame *frame) override; + + bool CalculateStopInfo() override; + + const char *GetInfo() override { return nullptr; } + + const char *GetName() override; + + const char *GetQueueName() override; + + void WillResume(lldb::StateType resume_state) override; + + void RefreshStateAfterStop() override; + + void ClearStackFrames() override; + +private: + void CheckInterpreterAndScriptObject() const; + lldb::ScriptedThreadInterfaceSP GetInterface() const; + + ScriptedThread(const ScriptedThread &) = delete; + const ScriptedThread &operator=(const ScriptedThread &) = delete; + + std::shared_ptr<DynamicRegisterInfo> GetDynamicRegisterInfo(); + + const ScriptedProcess &m_scripted_process; + std::shared_ptr<DynamicRegisterInfo> m_register_info_sp = nullptr; + lldb_private::StructuredData::ObjectSP m_script_object_sp = nullptr; +}; + +} // namespace lldb_private + +#endif // LLDB_SOURCE_PLUGINS_SCRIPTED_THREAD_H diff --git a/contrib/llvm-project/lldb/source/Plugins/REPL/Clang/ClangREPL.cpp b/contrib/llvm-project/lldb/source/Plugins/REPL/Clang/ClangREPL.cpp new file mode 100644 index 000000000000..5060dbb7ddba --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/REPL/Clang/ClangREPL.cpp @@ -0,0 +1,102 @@ +//===-- ClangREPL.cpp -----------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "ClangREPL.h" +#include "lldb/Core/Debugger.h" +#include "lldb/Core/PluginManager.h" +#include "lldb/Expression/ExpressionVariable.h" + +using namespace lldb_private; + +LLDB_PLUGIN_DEFINE(ClangREPL) + +ClangREPL::ClangREPL(lldb::LanguageType language, Target &target) + : REPL(eKindClang, target), m_language(language), + m_implicit_expr_result_regex("\\$[0-9]+") {} + +ClangREPL::~ClangREPL() {} + +void ClangREPL::Initialize() { + LanguageSet languages; + // FIXME: There isn't a way to ask CPlusPlusLanguage and ObjCLanguage for + // a list of languages they support. + languages.Insert(lldb::LanguageType::eLanguageTypeC); + languages.Insert(lldb::LanguageType::eLanguageTypeC89); + languages.Insert(lldb::LanguageType::eLanguageTypeC99); + languages.Insert(lldb::LanguageType::eLanguageTypeC11); + languages.Insert(lldb::LanguageType::eLanguageTypeC_plus_plus); + languages.Insert(lldb::LanguageType::eLanguageTypeC_plus_plus_03); + languages.Insert(lldb::LanguageType::eLanguageTypeC_plus_plus_11); + languages.Insert(lldb::LanguageType::eLanguageTypeC_plus_plus_14); + languages.Insert(lldb::LanguageType::eLanguageTypeObjC); + languages.Insert(lldb::LanguageType::eLanguageTypeObjC_plus_plus); + PluginManager::RegisterPlugin(GetPluginNameStatic(), "C language REPL", + &CreateInstance, languages); +} + +void ClangREPL::Terminate() { + PluginManager::UnregisterPlugin(&CreateInstance); +} + +lldb::REPLSP ClangREPL::CreateInstance(Status &error, + lldb::LanguageType language, + Debugger *debugger, Target *target, + const char *repl_options) { + // Creating a dummy target if only a debugger is given isn't implemented yet. + if (!target) { + error.SetErrorString("must have a target to create a REPL"); + return nullptr; + } + lldb::REPLSP result = std::make_shared<ClangREPL>(language, *target); + target->SetREPL(language, result); + error = Status(); + return result; +} + +Status ClangREPL::DoInitialization() { return Status(); } + +ConstString ClangREPL::GetSourceFileBasename() { + return ConstString("repl.c"); +} + +const char *ClangREPL::GetAutoIndentCharacters() { return " "; } + +bool ClangREPL::SourceIsComplete(const std::string &source) { + // FIXME: There isn't a good way to know if the input source is complete or + // not, so just say that every single REPL line is ready to be parsed. + return !source.empty(); +} + +lldb::offset_t ClangREPL::GetDesiredIndentation(const StringList &lines, + int cursor_position, + int tab_size) { + // FIXME: Not implemented. + return LLDB_INVALID_OFFSET; +} + +lldb::LanguageType ClangREPL::GetLanguage() { return m_language; } + +bool ClangREPL::PrintOneVariable(Debugger &debugger, + lldb::StreamFileSP &output_sp, + lldb::ValueObjectSP &valobj_sp, + ExpressionVariable *var) { + // If a ExpressionVariable was passed, check first if that variable is just + // an automatically created expression result. These variables are already + // printed by the REPL so this is done to prevent printing the variable twice. + if (var) { + if (m_implicit_expr_result_regex.Execute(var->GetName().GetStringRef())) + return true; + } + valobj_sp->Dump(*output_sp); + return true; +} + +void ClangREPL::CompleteCode(const std::string ¤t_code, + CompletionRequest &request) { + // Not implemented. +} diff --git a/contrib/llvm-project/lldb/source/Plugins/REPL/Clang/ClangREPL.h b/contrib/llvm-project/lldb/source/Plugins/REPL/Clang/ClangREPL.h new file mode 100644 index 000000000000..07b7f73b1faf --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/REPL/Clang/ClangREPL.h @@ -0,0 +1,63 @@ +//===-- ClangREPL.h ---------------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_SOURCE_PLUGINS_REPL_CLANG_CLANGREPL_H +#define LLDB_SOURCE_PLUGINS_REPL_CLANG_CLANGREPL_H + +#include "lldb/Expression/REPL.h" + +namespace lldb_private { +/// Implements a Clang-based REPL for C languages on top of LLDB's REPL +/// framework. +class ClangREPL : public REPL { +public: + ClangREPL(lldb::LanguageType language, Target &target); + + ~ClangREPL() override; + + static void Initialize(); + + static void Terminate(); + + static lldb::REPLSP CreateInstance(Status &error, lldb::LanguageType language, + Debugger *debugger, Target *target, + const char *repl_options); + + static llvm::StringRef GetPluginNameStatic() { return "ClangREPL"; } + +protected: + Status DoInitialization() override; + + ConstString GetSourceFileBasename() override; + + const char *GetAutoIndentCharacters() override; + + bool SourceIsComplete(const std::string &source) override; + + lldb::offset_t GetDesiredIndentation(const StringList &lines, + int cursor_position, + int tab_size) override; + + lldb::LanguageType GetLanguage() override; + + bool PrintOneVariable(Debugger &debugger, lldb::StreamFileSP &output_sp, + lldb::ValueObjectSP &valobj_sp, + ExpressionVariable *var = nullptr) override; + + void CompleteCode(const std::string ¤t_code, + CompletionRequest &request) override; + +private: + /// The specific C language of this REPL. + lldb::LanguageType m_language; + /// A regex matching the implicitly created LLDB result variables. + lldb_private::RegularExpression m_implicit_expr_result_regex; +}; +} // namespace lldb_private + +#endif // LLDB_SOURCE_PLUGINS_REPL_CLANG_CLANGREPL_H diff --git a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Lua/ScriptInterpreterLua.cpp b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Lua/ScriptInterpreterLua.cpp index ef46401c8b46..c677abfaa5f2 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Lua/ScriptInterpreterLua.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Lua/ScriptInterpreterLua.cpp @@ -148,6 +148,12 @@ ScriptInterpreterLua::ScriptInterpreterLua(Debugger &debugger) ScriptInterpreterLua::~ScriptInterpreterLua() = default; +StructuredData::DictionarySP ScriptInterpreterLua::GetInterpreterInfo() { + auto info = std::make_shared<StructuredData::Dictionary>(); + info->AddStringItem("language", "lua"); + return info; +} + bool ScriptInterpreterLua::ExecuteOneLine(llvm::StringRef command, CommandReturnObject *result, const ExecuteScriptOptions &options) { @@ -387,19 +393,8 @@ ScriptInterpreterLua::CreateInstance(Debugger &debugger) { return std::make_shared<ScriptInterpreterLua>(debugger); } -lldb_private::ConstString ScriptInterpreterLua::GetPluginNameStatic() { - static ConstString g_name("script-lua"); - return g_name; -} - -const char *ScriptInterpreterLua::GetPluginDescriptionStatic() { +llvm::StringRef ScriptInterpreterLua::GetPluginDescriptionStatic() { return "Lua script interpreter"; } -lldb_private::ConstString ScriptInterpreterLua::GetPluginName() { - return GetPluginNameStatic(); -} - -uint32_t ScriptInterpreterLua::GetPluginVersion() { return 1; } - Lua &ScriptInterpreterLua::GetLua() { return *m_lua; } diff --git a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Lua/ScriptInterpreterLua.h b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Lua/ScriptInterpreterLua.h index 808000b833ec..b601779ff301 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Lua/ScriptInterpreterLua.h +++ b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Lua/ScriptInterpreterLua.h @@ -49,6 +49,8 @@ public: StructuredData::ObjectSP *module_sp = nullptr, FileSpec extra_search_dir = {}) override; + StructuredData::DictionarySP GetInterpreterInfo() override; + // Static Functions static void Initialize(); @@ -56,9 +58,9 @@ public: static lldb::ScriptInterpreterSP CreateInstance(Debugger &debugger); - static lldb_private::ConstString GetPluginNameStatic(); + static llvm::StringRef GetPluginNameStatic() { return "script-lua"; } - static const char *GetPluginDescriptionStatic(); + static llvm::StringRef GetPluginDescriptionStatic(); static bool BreakpointCallbackFunction(void *baton, StoppointCallbackContext *context, @@ -70,9 +72,7 @@ public: lldb::user_id_t watch_id); // PluginInterface protocol - lldb_private::ConstString GetPluginName() override; - - uint32_t GetPluginVersion() override; + llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); } Lua &GetLua(); diff --git a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/None/ScriptInterpreterNone.cpp b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/None/ScriptInterpreterNone.cpp index f8a385240bd9..bec90b2038e1 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/None/ScriptInterpreterNone.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/None/ScriptInterpreterNone.cpp @@ -57,17 +57,6 @@ ScriptInterpreterNone::CreateInstance(Debugger &debugger) { return std::make_shared<ScriptInterpreterNone>(debugger); } -lldb_private::ConstString ScriptInterpreterNone::GetPluginNameStatic() { - static ConstString g_name("script-none"); - return g_name; -} - -const char *ScriptInterpreterNone::GetPluginDescriptionStatic() { +llvm::StringRef ScriptInterpreterNone::GetPluginDescriptionStatic() { return "Null script interpreter"; } - -lldb_private::ConstString ScriptInterpreterNone::GetPluginName() { - return GetPluginNameStatic(); -} - -uint32_t ScriptInterpreterNone::GetPluginVersion() { return 1; } diff --git a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/None/ScriptInterpreterNone.h b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/None/ScriptInterpreterNone.h index c438b6315c5d..6d3ff251e362 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/None/ScriptInterpreterNone.h +++ b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/None/ScriptInterpreterNone.h @@ -32,14 +32,12 @@ public: static lldb::ScriptInterpreterSP CreateInstance(Debugger &debugger); - static lldb_private::ConstString GetPluginNameStatic(); + static llvm::StringRef GetPluginNameStatic() { return "script-none"; } - static const char *GetPluginDescriptionStatic(); + static llvm::StringRef GetPluginDescriptionStatic(); // PluginInterface protocol - lldb_private::ConstString GetPluginName() override; - - uint32_t GetPluginVersion() override; + llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); } }; } // namespace lldb_private diff --git a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp index f51d9b3a796c..7c71c9329e57 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp @@ -998,20 +998,6 @@ bool PythonFile::Check(PyObject *py_obj) { #endif } -namespace { -class GIL { -public: - GIL() { - m_state = PyGILState_Ensure(); - assert(!PyErr_Occurred()); - } - ~GIL() { PyGILState_Release(m_state); } - -protected: - PyGILState_STATE m_state; -}; -} // namespace - const char *PythonException::toCString() const { if (!m_repr_bytes) return "unknown exception"; @@ -1114,10 +1100,12 @@ GetOptionsForPyObject(const PythonObject &obj) { auto writable = As<bool>(obj.CallMethod("writable")); if (!writable) return writable.takeError(); - if (readable.get()) - options |= File::eOpenOptionRead; - if (writable.get()) - options |= File::eOpenOptionWrite; + if (readable.get() && writable.get()) + options |= File::eOpenOptionReadWrite; + else if (writable.get()) + options |= File::eOpenOptionWriteOnly; + else if (readable.get()) + options |= File::eOpenOptionReadOnly; return options; #else PythonString py_mode = obj.GetAttributeValue("mode").AsType<PythonString>(); @@ -1413,7 +1401,10 @@ llvm::Expected<FileSP> PythonFile::ConvertToFile(bool borrowed) { if (!options) return options.takeError(); - if (options.get() & File::eOpenOptionWrite) { + File::OpenOptions rw = + options.get() & (File::eOpenOptionReadOnly | File::eOpenOptionWriteOnly | + File::eOpenOptionReadWrite); + if (rw == File::eOpenOptionWriteOnly || rw == File::eOpenOptionReadWrite) { // LLDB and python will not share I/O buffers. We should probably // flush the python buffers now. auto r = CallMethod("flush"); diff --git a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h index 4577253227cd..56bc55d239d1 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h +++ b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h @@ -71,6 +71,18 @@ class PythonDictionary; class PythonInteger; class PythonException; +class GIL { +public: + GIL() { + m_state = PyGILState_Ensure(); + assert(!PyErr_Occurred()); + } + ~GIL() { PyGILState_Release(m_state); } + +protected: + PyGILState_STATE m_state; +}; + class StructuredPythonObject : public StructuredData::Generic { public: StructuredPythonObject() : StructuredData::Generic() {} diff --git a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/SWIGPythonBridge.h b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/SWIGPythonBridge.h index 1ef792bcf303..798d947a0a7d 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/SWIGPythonBridge.h +++ b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/SWIGPythonBridge.h @@ -46,9 +46,15 @@ extern "C" void *LLDBSwigPythonCreateScriptedProcess( const lldb::TargetSP &target_sp, StructuredDataImpl *args_impl, std::string &error_string); +extern "C" void *LLDBSwigPythonCreateScriptedThread( + const char *python_class_name, const char *session_dictionary_name, + const lldb::ProcessSP &process_sp, StructuredDataImpl *args_impl, + std::string &error_string); + extern "C" void *LLDBSWIGPython_CastPyObjectToSBData(void *data); extern "C" void *LLDBSWIGPython_CastPyObjectToSBError(void *data); extern "C" void *LLDBSWIGPython_CastPyObjectToSBValue(void *data); +extern "C" void *LLDBSWIGPython_CastPyObjectToSBMemoryRegionInfo(void *data); } // namespace lldb_private diff --git a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp index 7ad63722c31c..c1f4c2d3b4d3 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp @@ -355,7 +355,6 @@ private: PyEval_InitThreads(); } - TerminalState m_stdin_tty_state; PyGILState_STATE m_gil_state = PyGILState_UNLOCKED; bool m_was_already_initialized = false; }; @@ -411,6 +410,36 @@ FileSpec ScriptInterpreterPython::GetPythonDir() { return g_spec; } +static const char GetInterpreterInfoScript[] = R"( +import os +import sys + +def main(lldb_python_dir, python_exe_relative_path): + info = { + "lldb-pythonpath": lldb_python_dir, + "language": "python", + "prefix": sys.prefix, + "executable": os.path.join(sys.prefix, python_exe_relative_path) + } + return info +)"; + +static const char python_exe_relative_path[] = LLDB_PYTHON_EXE_RELATIVE_PATH; + +StructuredData::DictionarySP ScriptInterpreterPython::GetInterpreterInfo() { + GIL gil; + FileSpec python_dir_spec = GetPythonDir(); + if (!python_dir_spec) + return nullptr; + PythonScript get_info(GetInterpreterInfoScript); + auto info_json = unwrapIgnoringErrors( + As<PythonDictionary>(get_info(PythonString(python_dir_spec.GetPath()), + PythonString(python_exe_relative_path)))); + if (!info_json) + return nullptr; + return info_json.CreateStructuredDictionary(); +} + void ScriptInterpreterPython::SharedLibraryDirectoryHelper( FileSpec &this_file) { // When we're loaded from python, this_file will point to the file inside the @@ -437,12 +466,7 @@ void ScriptInterpreterPython::SharedLibraryDirectoryHelper( #endif } -lldb_private::ConstString ScriptInterpreterPython::GetPluginNameStatic() { - static ConstString g_name("script-python"); - return g_name; -} - -const char *ScriptInterpreterPython::GetPluginDescriptionStatic() { +llvm::StringRef ScriptInterpreterPython::GetPluginDescriptionStatic() { return "Embedded Python interpreter"; } @@ -591,12 +615,6 @@ ScriptInterpreterPythonImpl::~ScriptInterpreterPythonImpl() { PyGILState_Release(gil_state); } -lldb_private::ConstString ScriptInterpreterPythonImpl::GetPluginName() { - return GetPluginNameStatic(); -} - -uint32_t ScriptInterpreterPythonImpl::GetPluginVersion() { return 1; } - void ScriptInterpreterPythonImpl::IOHandlerActivated(IOHandler &io_handler, bool interactive) { const char *instructions = nullptr; diff --git a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.h b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.h index b8b978118218..8cfc24e71283 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.h +++ b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.h @@ -13,8 +13,6 @@ #if LLDB_ENABLE_PYTHON -#include "ScriptedProcessPythonInterface.h" - #include "lldb/Breakpoint/BreakpointOptions.h" #include "lldb/Core/IOHandler.h" #include "lldb/Core/StructuredDataImpl.h" @@ -48,10 +46,11 @@ public: : ScriptInterpreter(debugger, lldb::eScriptLanguagePython), IOHandlerDelegateMultiline("DONE") {} + StructuredData::DictionarySP GetInterpreterInfo() override; static void Initialize(); static void Terminate(); - static lldb_private::ConstString GetPluginNameStatic(); - static const char *GetPluginDescriptionStatic(); + static llvm::StringRef GetPluginNameStatic() { return "script-python"; } + static llvm::StringRef GetPluginDescriptionStatic(); static FileSpec GetPythonDir(); static void SharedLibraryDirectoryHelper(FileSpec &this_file); diff --git a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h index d1b0b3fda1ef..a3f83b696ed4 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h +++ b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h @@ -292,9 +292,7 @@ public: static lldb::ScriptInterpreterSP CreateInstance(Debugger &debugger); // PluginInterface protocol - lldb_private::ConstString GetPluginName() override; - - uint32_t GetPluginVersion() override; + llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); } class Locker : public ScriptInterpreterLocker { public: @@ -432,13 +430,12 @@ public: int stdin_fd = GetInputFD(); if (stdin_fd >= 0) { Terminal terminal(stdin_fd); - TerminalState terminal_state; - const bool is_a_tty = terminal.IsATerminal(); + TerminalState terminal_state(terminal); - if (is_a_tty) { - terminal_state.Save(stdin_fd, false); - terminal.SetCanonical(false); - terminal.SetEcho(true); + if (terminal.IsATerminal()) { + // FIXME: error handling? + llvm::consumeError(terminal.SetCanonical(false)); + llvm::consumeError(terminal.SetEcho(true)); } ScriptInterpreterPythonImpl::Locker locker( @@ -466,9 +463,6 @@ public: run_string.Printf("run_python_interpreter (%s)", m_python->GetDictionaryName()); PyRun_SimpleString(run_string.GetData()); - - if (is_a_tty) - terminal_state.Restore(); } } SetIsDone(true); diff --git a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.cpp b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.cpp index ce262c930f8b..29680dab5a14 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.cpp @@ -7,6 +7,8 @@ //===----------------------------------------------------------------------===// #include "lldb/Host/Config.h" +#include "lldb/Utility/Log.h" +#include "lldb/Utility/Logging.h" #include "lldb/lldb-enumerations.h" #if LLDB_ENABLE_PYTHON @@ -17,36 +19,40 @@ #include "SWIGPythonBridge.h" #include "ScriptInterpreterPythonImpl.h" #include "ScriptedProcessPythonInterface.h" +#include "ScriptedThreadPythonInterface.h" using namespace lldb; using namespace lldb_private; using namespace lldb_private::python; using Locker = ScriptInterpreterPythonImpl::Locker; +ScriptedProcessPythonInterface::ScriptedProcessPythonInterface( + ScriptInterpreterPythonImpl &interpreter) + : ScriptedProcessInterface(), ScriptedPythonInterface(interpreter) {} + StructuredData::GenericSP ScriptedProcessPythonInterface::CreatePluginObject( - const llvm::StringRef class_name, lldb::TargetSP target_sp, + llvm::StringRef class_name, ExecutionContext &exe_ctx, StructuredData::DictionarySP args_sp) { if (class_name.empty()) return {}; - std::string error_string; + TargetSP target_sp = exe_ctx.GetTargetSP(); StructuredDataImpl *args_impl = nullptr; if (args_sp) { args_impl = new StructuredDataImpl(); args_impl->SetObjectSP(args_sp); } + std::string error_string; - void *ret_val; - - { + Locker py_lock(&m_interpreter, Locker::AcquireLock | Locker::NoSTDIN, + Locker::FreeLock); - Locker py_lock(&m_interpreter, Locker::AcquireLock | Locker::NoSTDIN, - Locker::FreeLock); + void *ret_val = LLDBSwigPythonCreateScriptedProcess( + class_name.str().c_str(), m_interpreter.GetDictionaryName(), target_sp, + args_impl, error_string); - ret_val = LLDBSwigPythonCreateScriptedProcess( - class_name.str().c_str(), m_interpreter.GetDictionaryName(), target_sp, - args_impl, error_string); - } + if (!ret_val) + return {}; m_object_instance_sp = StructuredData::GenericSP(new StructuredPythonObject(ret_val)); @@ -63,244 +69,101 @@ Status ScriptedProcessPythonInterface::Resume() { } bool ScriptedProcessPythonInterface::ShouldStop() { - llvm::Optional<unsigned long long> should_stop = - GetGenericInteger("should_stop"); + Status error; + StructuredData::ObjectSP obj = Dispatch("is_alive", error); - if (!should_stop) - return false; + if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj, error)) + return {}; - return static_cast<bool>(*should_stop); + return obj->GetBooleanValue(); } Status ScriptedProcessPythonInterface::Stop() { return GetStatusFromMethod("stop"); } -Status ScriptedProcessPythonInterface::GetStatusFromMethod( - llvm::StringRef method_name) { - Locker py_lock(&m_interpreter, Locker::AcquireLock | Locker::NoSTDIN, - Locker::FreeLock); - - if (!m_object_instance_sp) - return Status("Python object ill-formed."); - - if (!m_object_instance_sp) - return Status("Cannot convert Python object to StructuredData::Generic."); - PythonObject implementor(PyRefType::Borrowed, - (PyObject *)m_object_instance_sp->GetValue()); - - if (!implementor.IsAllocated()) - return Status("Python implementor not allocated."); - - PythonObject pmeth( - PyRefType::Owned, - PyObject_GetAttrString(implementor.get(), method_name.str().c_str())); - - if (PyErr_Occurred()) - PyErr_Clear(); - - if (!pmeth.IsAllocated()) - return Status("Python method not allocated."); - - if (PyCallable_Check(pmeth.get()) == 0) { - if (PyErr_Occurred()) - PyErr_Clear(); - return Status("Python method not callable."); - } - - if (PyErr_Occurred()) - PyErr_Clear(); - - PythonObject py_return(PyRefType::Owned, - PyObject_CallMethod(implementor.get(), - method_name.str().c_str(), - nullptr)); - - if (PyErr_Occurred()) { - PyErr_Print(); - PyErr_Clear(); - return Status("Python method could not be called."); - } - - if (PyObject *py_ret_ptr = py_return.get()) { - lldb::SBError *sb_error = - (lldb::SBError *)LLDBSWIGPython_CastPyObjectToSBError(py_ret_ptr); - - if (!sb_error) - return Status("Couldn't cast lldb::SBError to lldb::Status."); - - Status status = m_interpreter.GetStatusFromSBError(*sb_error); - - if (status.Fail()) - return Status("error: %s", status.AsCString()); +llvm::Optional<MemoryRegionInfo> +ScriptedProcessPythonInterface::GetMemoryRegionContainingAddress( + lldb::addr_t address, Status &error) { + auto mem_region = Dispatch<llvm::Optional<MemoryRegionInfo>>( + "get_memory_region_containing_address", error, address); - return status; + if (error.Fail()) { + return ErrorWithMessage<MemoryRegionInfo>(LLVM_PRETTY_FUNCTION, + error.AsCString(), error); } - return Status("Returned object is null."); + return mem_region; } -llvm::Optional<unsigned long long> -ScriptedProcessPythonInterface::GetGenericInteger(llvm::StringRef method_name) { - Locker py_lock(&m_interpreter, Locker::AcquireLock | Locker::NoSTDIN, - Locker::FreeLock); - - if (!m_object_instance_sp) - return llvm::None; - - if (!m_object_instance_sp) - return llvm::None; - PythonObject implementor(PyRefType::Borrowed, - (PyObject *)m_object_instance_sp->GetValue()); - - if (!implementor.IsAllocated()) - return llvm::None; - - PythonObject pmeth( - PyRefType::Owned, - PyObject_GetAttrString(implementor.get(), method_name.str().c_str())); - - if (PyErr_Occurred()) - PyErr_Clear(); - - if (!pmeth.IsAllocated()) - return llvm::None; - - if (PyCallable_Check(pmeth.get()) == 0) { - if (PyErr_Occurred()) - PyErr_Clear(); - return llvm::None; - } - - if (PyErr_Occurred()) - PyErr_Clear(); - - PythonObject py_return(PyRefType::Owned, - PyObject_CallMethod(implementor.get(), - method_name.str().c_str(), - nullptr)); - - if (PyErr_Occurred()) { - PyErr_Print(); - PyErr_Clear(); - } - - if (!py_return.get()) - return llvm::None; +StructuredData::DictionarySP +ScriptedProcessPythonInterface::GetThreadWithID(lldb::tid_t tid) { + Status error; + StructuredData::ObjectSP obj = Dispatch("get_thread_with_id", error, tid); - llvm::Expected<unsigned long long> size = py_return.AsUnsignedLongLong(); - // FIXME: Handle error. - if (!size) - return llvm::None; + if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj, error)) + return {}; - return *size; -} + StructuredData::DictionarySP dict{obj->GetAsDictionary()}; -lldb::MemoryRegionInfoSP -ScriptedProcessPythonInterface::GetMemoryRegionContainingAddress( - lldb::addr_t address) { - // TODO: Implement - return nullptr; -} - -StructuredData::DictionarySP -ScriptedProcessPythonInterface::GetThreadWithID(lldb::tid_t tid) { - // TODO: Implement - return nullptr; + return dict; } StructuredData::DictionarySP ScriptedProcessPythonInterface::GetRegistersForThread(lldb::tid_t tid) { // TODO: Implement - return nullptr; + return {}; } lldb::DataExtractorSP ScriptedProcessPythonInterface::ReadMemoryAtAddress( lldb::addr_t address, size_t size, Status &error) { - Locker py_lock(&m_interpreter, Locker::AcquireLock | Locker::NoSTDIN, - Locker::FreeLock); - - auto error_with_message = [&error](llvm::StringRef message) { - error.SetErrorString(message); - return nullptr; - }; - - static char callee_name[] = "read_memory_at_address"; - std::string param_format = GetPythonValueFormatString(address); - param_format += GetPythonValueFormatString(size); - - if (!m_object_instance_sp) - return error_with_message("Python object ill-formed."); - - if (!m_object_instance_sp) - return error_with_message("Python method not callable."); - - PythonObject implementor(PyRefType::Borrowed, - (PyObject *)m_object_instance_sp->GetValue()); - - if (!implementor.IsAllocated()) - return error_with_message("Python implementor not allocated."); - - PythonObject pmeth(PyRefType::Owned, - PyObject_GetAttrString(implementor.get(), callee_name)); - - if (PyErr_Occurred()) - PyErr_Clear(); - - if (!pmeth.IsAllocated()) - return error_with_message("Python method not allocated."); - - if (PyCallable_Check(pmeth.get()) == 0) { - if (PyErr_Occurred()) - PyErr_Clear(); - return error_with_message("Python method not callable."); - } + return Dispatch<lldb::DataExtractorSP>("read_memory_at_address", error, + address, size); +} - if (PyErr_Occurred()) - PyErr_Clear(); +StructuredData::DictionarySP ScriptedProcessPythonInterface::GetLoadedImages() { + // TODO: Implement + return {}; +} - PythonObject py_return(PyRefType::Owned, - PyObject_CallMethod(implementor.get(), callee_name, - param_format.c_str(), address, - size)); +lldb::pid_t ScriptedProcessPythonInterface::GetProcessID() { + Status error; + StructuredData::ObjectSP obj = Dispatch("get_process_id", error); - if (PyErr_Occurred()) { - PyErr_Print(); - PyErr_Clear(); - return error_with_message("Python method could not be called."); - } + if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj, error)) + return LLDB_INVALID_PROCESS_ID; - if (PyObject *py_ret_ptr = py_return.get()) { - lldb::SBData *sb_data = - (lldb::SBData *)LLDBSWIGPython_CastPyObjectToSBData(py_ret_ptr); + return obj->GetIntegerValue(LLDB_INVALID_PROCESS_ID); +} - if (!sb_data) - return error_with_message( - "Couldn't cast lldb::SBData to lldb::DataExtractor."); +bool ScriptedProcessPythonInterface::IsAlive() { + Status error; + StructuredData::ObjectSP obj = Dispatch("is_alive", error); - return m_interpreter.GetDataExtractorFromSBData(*sb_data); - } + if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj, error)) + return {}; - return error_with_message("Returned object is null."); + return obj->GetBooleanValue(); } -StructuredData::DictionarySP ScriptedProcessPythonInterface::GetLoadedImages() { - // TODO: Implement - return nullptr; -} +llvm::Optional<std::string> +ScriptedProcessPythonInterface::GetScriptedThreadPluginName() { + Status error; + StructuredData::ObjectSP obj = Dispatch("get_scripted_thread_plugin", error); -lldb::pid_t ScriptedProcessPythonInterface::GetProcessID() { - llvm::Optional<unsigned long long> pid = GetGenericInteger("get_process_id"); - return (!pid) ? LLDB_INVALID_PROCESS_ID : *pid; -} + if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj, error)) + return {}; -bool ScriptedProcessPythonInterface::IsAlive() { - llvm::Optional<unsigned long long> is_alive = GetGenericInteger("is_alive"); + return obj->GetStringValue().str(); +} - if (!is_alive) - return false; +lldb::ScriptedThreadInterfaceSP +ScriptedProcessPythonInterface::GetScriptedThreadInterface() { + if (!m_scripted_thread_interface_sp) + m_scripted_thread_interface_sp = + std::make_shared<ScriptedThreadPythonInterface>(m_interpreter); - return static_cast<bool>(*is_alive); + return m_scripted_thread_interface_sp; } #endif diff --git a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.h b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.h index 30cb5a882af2..421bdd59887c 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.h +++ b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.h @@ -13,17 +13,18 @@ #if LLDB_ENABLE_PYTHON +#include "ScriptedPythonInterface.h" #include "lldb/Interpreter/ScriptedProcessInterface.h" namespace lldb_private { -class ScriptInterpreterPythonImpl; -class ScriptedProcessPythonInterface : public ScriptedProcessInterface { +class ScriptedProcessPythonInterface : public ScriptedProcessInterface, + public ScriptedPythonInterface { public: - ScriptedProcessPythonInterface(ScriptInterpreterPythonImpl &interpreter) - : ScriptedProcessInterface(), m_interpreter(interpreter) {} + ScriptedProcessPythonInterface(ScriptInterpreterPythonImpl &interpreter); StructuredData::GenericSP - CreatePluginObject(const llvm::StringRef class_name, lldb::TargetSP target_sp, + CreatePluginObject(const llvm::StringRef class_name, + ExecutionContext &exe_ctx, StructuredData::DictionarySP args_sp) override; Status Launch() override; @@ -34,8 +35,9 @@ public: Status Stop() override; - lldb::MemoryRegionInfoSP - GetMemoryRegionContainingAddress(lldb::addr_t address) override; + llvm::Optional<MemoryRegionInfo> + GetMemoryRegionContainingAddress(lldb::addr_t address, + Status &error) override; StructuredData::DictionarySP GetThreadWithID(lldb::tid_t tid) override; @@ -50,15 +52,10 @@ public: bool IsAlive() override; -protected: - llvm::Optional<unsigned long long> - GetGenericInteger(llvm::StringRef method_name); - Status GetStatusFromMethod(llvm::StringRef method_name); + llvm::Optional<std::string> GetScriptedThreadPluginName() override; private: - // The lifetime is managed by the ScriptInterpreter - ScriptInterpreterPythonImpl &m_interpreter; - StructuredData::GenericSP m_object_instance_sp; + lldb::ScriptedThreadInterfaceSP GetScriptedThreadInterface() override; }; } // namespace lldb_private diff --git a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedPythonInterface.cpp b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedPythonInterface.cpp new file mode 100644 index 000000000000..07bf952bf840 --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedPythonInterface.cpp @@ -0,0 +1,92 @@ +//===-- ScriptedPythonInterface.cpp ---------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "lldb/Host/Config.h" +#include "lldb/Utility/Log.h" +#include "lldb/Utility/Logging.h" +#include "lldb/lldb-enumerations.h" + +#if LLDB_ENABLE_PYTHON + +// LLDB Python header must be included first +#include "lldb-python.h" + +#include "SWIGPythonBridge.h" +#include "ScriptInterpreterPythonImpl.h" +#include "ScriptedPythonInterface.h" + +using namespace lldb; +using namespace lldb_private; + +ScriptedPythonInterface::ScriptedPythonInterface( + ScriptInterpreterPythonImpl &interpreter) + : ScriptedInterface(), m_interpreter(interpreter) {} + +Status +ScriptedPythonInterface::GetStatusFromMethod(llvm::StringRef method_name) { + Status error; + Dispatch<Status>(method_name, error); + + return error; +} + +template <> +StructuredData::DictionarySP +ScriptedPythonInterface::ExtractValueFromPythonObject< + StructuredData::DictionarySP>(python::PythonObject &p, Status &error) { + python::PythonDictionary result_dict(python::PyRefType::Borrowed, p.get()); + return result_dict.CreateStructuredDictionary(); +} + +template <> +Status ScriptedPythonInterface::ExtractValueFromPythonObject<Status>( + python::PythonObject &p, Status &error) { + if (lldb::SBError *sb_error = reinterpret_cast<lldb::SBError *>( + LLDBSWIGPython_CastPyObjectToSBError(p.get()))) + error = m_interpreter.GetStatusFromSBError(*sb_error); + else + error.SetErrorString("Couldn't cast lldb::SBError to lldb::Status."); + + return error; +} + +template <> +lldb::DataExtractorSP +ScriptedPythonInterface::ExtractValueFromPythonObject<lldb::DataExtractorSP>( + python::PythonObject &p, Status &error) { + lldb::SBData *sb_data = reinterpret_cast<lldb::SBData *>( + LLDBSWIGPython_CastPyObjectToSBData(p.get())); + + if (!sb_data) { + error.SetErrorString( + "Couldn't cast lldb::SBData to lldb::DataExtractorSP."); + return nullptr; + } + + return m_interpreter.GetDataExtractorFromSBData(*sb_data); +} + +template <> +llvm::Optional<MemoryRegionInfo> +ScriptedPythonInterface::ExtractValueFromPythonObject< + llvm::Optional<MemoryRegionInfo>>(python::PythonObject &p, Status &error) { + + lldb::SBMemoryRegionInfo *sb_mem_reg_info = + reinterpret_cast<lldb::SBMemoryRegionInfo *>( + LLDBSWIGPython_CastPyObjectToSBMemoryRegionInfo(p.get())); + + if (!sb_mem_reg_info) { + error.SetErrorString( + "Couldn't cast lldb::SBMemoryRegionInfo to lldb::MemoryRegionInfoSP."); + return {}; + } + + return m_interpreter.GetOpaqueTypeFromSBMemoryRegionInfo(*sb_mem_reg_info); +} + +#endif diff --git a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedPythonInterface.h b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedPythonInterface.h new file mode 100644 index 000000000000..da112eb72022 --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedPythonInterface.h @@ -0,0 +1,151 @@ +//===-- ScriptedPythonInterface.h -------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_SCRIPTEDPYTHONINTERFACE_H +#define LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_SCRIPTEDPYTHONINTERFACE_H + +#include "lldb/Host/Config.h" + +#if LLDB_ENABLE_PYTHON + +#include "lldb/Interpreter/ScriptedInterface.h" +#include "lldb/Utility/DataBufferHeap.h" + +#include "PythonDataObjects.h" +#include "SWIGPythonBridge.h" +#include "ScriptInterpreterPythonImpl.h" + +namespace lldb_private { +class ScriptInterpreterPythonImpl; +class ScriptedPythonInterface : virtual public ScriptedInterface { +public: + ScriptedPythonInterface(ScriptInterpreterPythonImpl &interpreter); + virtual ~ScriptedPythonInterface() = default; + +protected: + template <typename T = StructuredData::ObjectSP> + T ExtractValueFromPythonObject(python::PythonObject &p, Status &error) { + return p.CreateStructuredObject(); + } + + template <typename T = StructuredData::ObjectSP, typename... Args> + T Dispatch(llvm::StringRef method_name, Status &error, Args... args) { + using namespace python; + using Locker = ScriptInterpreterPythonImpl::Locker; + + std::string caller_signature = + llvm::Twine(LLVM_PRETTY_FUNCTION + llvm::Twine(" (") + + llvm::Twine(method_name) + llvm::Twine(")")) + .str(); + if (!m_object_instance_sp) + return ErrorWithMessage<T>(caller_signature, "Python object ill-formed", + error); + + Locker py_lock(&m_interpreter, Locker::AcquireLock | Locker::NoSTDIN, + Locker::FreeLock); + + PythonObject implementor(PyRefType::Borrowed, + (PyObject *)m_object_instance_sp->GetValue()); + + if (!implementor.IsAllocated()) + return ErrorWithMessage<T>(caller_signature, + "Python implementor not allocated.", error); + + PythonObject pmeth( + PyRefType::Owned, + PyObject_GetAttrString(implementor.get(), method_name.str().c_str())); + + if (PyErr_Occurred()) + PyErr_Clear(); + + if (!pmeth.IsAllocated()) + return ErrorWithMessage<T>(caller_signature, + "Python method not allocated.", error); + + if (PyCallable_Check(pmeth.get()) == 0) { + if (PyErr_Occurred()) + PyErr_Clear(); + return ErrorWithMessage<T>(caller_signature, + "Python method not callable.", error); + } + + if (PyErr_Occurred()) + PyErr_Clear(); + + // TODO: make `const char *` when removing support for Python 2. + char *format = nullptr; + std::string format_buffer; + + if (sizeof...(Args) > 0) { + FormatArgs(format_buffer, args...); + // TODO: make `const char *` when removing support for Python 2. + format = const_cast<char *>(format_buffer.c_str()); + } + + // TODO: make `const char *` when removing support for Python 2. + PythonObject py_return( + PyRefType::Owned, + PyObject_CallMethod(implementor.get(), + const_cast<char *>(method_name.data()), format, + args...)); + + if (PyErr_Occurred()) { + PyErr_Print(); + PyErr_Clear(); + return ErrorWithMessage<T>(caller_signature, + "Python method could not be called.", error); + } + + if (!py_return.IsAllocated()) + return ErrorWithMessage<T>(caller_signature, "Returned object is null.", + error); + + return ExtractValueFromPythonObject<T>(py_return, error); + } + + Status GetStatusFromMethod(llvm::StringRef method_name); + + template <typename T, typename... Args> + void FormatArgs(std::string &fmt, T arg, Args... args) const { + FormatArgs(fmt, arg); + FormatArgs(fmt, args...); + } + + template <typename T> void FormatArgs(std::string &fmt, T arg) const { + fmt += GetPythonValueFormatString(arg); + } + + void FormatArgs(std::string &fmt) const {} + + // The lifetime is managed by the ScriptInterpreter + ScriptInterpreterPythonImpl &m_interpreter; +}; + +template <> +StructuredData::DictionarySP +ScriptedPythonInterface::ExtractValueFromPythonObject< + StructuredData::DictionarySP>(python::PythonObject &p, Status &error); + +template <> +Status ScriptedPythonInterface::ExtractValueFromPythonObject<Status>( + python::PythonObject &p, Status &error); + +template <> +lldb::DataExtractorSP +ScriptedPythonInterface::ExtractValueFromPythonObject<lldb::DataExtractorSP>( + python::PythonObject &p, Status &error); + +template <> +llvm::Optional<MemoryRegionInfo> +ScriptedPythonInterface::ExtractValueFromPythonObject< + llvm::Optional<MemoryRegionInfo>>(python::PythonObject &p, Status &error); + +} // namespace lldb_private + +#endif // LLDB_ENABLE_PYTHON +#endif // LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_SCRIPTEDPYTHONINTERFACE_H diff --git a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedThreadPythonInterface.cpp b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedThreadPythonInterface.cpp new file mode 100644 index 000000000000..d2c28bc426ee --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedThreadPythonInterface.cpp @@ -0,0 +1,140 @@ +//===-- ScriptedThreadPythonInterface.cpp ---------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "lldb/Host/Config.h" +#include "lldb/Utility/Log.h" +#include "lldb/Utility/Logging.h" +#include "lldb/lldb-enumerations.h" + +#if LLDB_ENABLE_PYTHON + +// LLDB Python header must be included first +#include "lldb-python.h" + +#include "SWIGPythonBridge.h" +#include "ScriptInterpreterPythonImpl.h" +#include "ScriptedThreadPythonInterface.h" + +using namespace lldb; +using namespace lldb_private; +using namespace lldb_private::python; +using Locker = ScriptInterpreterPythonImpl::Locker; + +ScriptedThreadPythonInterface::ScriptedThreadPythonInterface( + ScriptInterpreterPythonImpl &interpreter) + : ScriptedThreadInterface(), ScriptedPythonInterface(interpreter) {} + +StructuredData::GenericSP ScriptedThreadPythonInterface::CreatePluginObject( + const llvm::StringRef class_name, ExecutionContext &exe_ctx, + StructuredData::DictionarySP args_sp) { + + if (class_name.empty()) + return {}; + + ProcessSP process_sp = exe_ctx.GetProcessSP(); + StructuredDataImpl *args_impl = nullptr; + if (args_sp) { + args_impl = new StructuredDataImpl(); + args_impl->SetObjectSP(args_sp); + } + std::string error_string; + + Locker py_lock(&m_interpreter, Locker::AcquireLock | Locker::NoSTDIN, + Locker::FreeLock); + + void *ret_val = LLDBSwigPythonCreateScriptedThread( + class_name.str().c_str(), m_interpreter.GetDictionaryName(), process_sp, + args_impl, error_string); + + if (!ret_val) + return {}; + + m_object_instance_sp = + StructuredData::GenericSP(new StructuredPythonObject(ret_val)); + + return m_object_instance_sp; +} + +lldb::tid_t ScriptedThreadPythonInterface::GetThreadID() { + Status error; + StructuredData::ObjectSP obj = Dispatch("get_thread_id", error); + + if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj, error)) + return LLDB_INVALID_THREAD_ID; + + return obj->GetIntegerValue(LLDB_INVALID_THREAD_ID); +} + +llvm::Optional<std::string> ScriptedThreadPythonInterface::GetName() { + Status error; + StructuredData::ObjectSP obj = Dispatch("get_name", error); + + if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj, error)) + return {}; + + return obj->GetStringValue().str(); +} + +lldb::StateType ScriptedThreadPythonInterface::GetState() { + Status error; + StructuredData::ObjectSP obj = Dispatch("get_state", error); + + if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj, error)) + return eStateInvalid; + + return static_cast<StateType>(obj->GetIntegerValue(eStateInvalid)); +} + +llvm::Optional<std::string> ScriptedThreadPythonInterface::GetQueue() { + Status error; + StructuredData::ObjectSP obj = Dispatch("get_queue", error); + + if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj, error)) + return {}; + + return obj->GetStringValue().str(); +} + +StructuredData::DictionarySP ScriptedThreadPythonInterface::GetStopReason() { + Status error; + StructuredData::DictionarySP dict = + Dispatch<StructuredData::DictionarySP>("get_stop_reason", error); + + if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, dict, error)) + return {}; + + return dict; +} + +StructuredData::ArraySP ScriptedThreadPythonInterface::GetStackFrames() { + return nullptr; +} + +StructuredData::DictionarySP ScriptedThreadPythonInterface::GetRegisterInfo() { + Status error; + StructuredData::DictionarySP dict = + Dispatch<StructuredData::DictionarySP>("get_register_info", error); + + if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, dict, error)) + return {}; + + return dict; +} + +llvm::Optional<std::string> +ScriptedThreadPythonInterface::GetRegisterContext() { + Status error; + StructuredData::ObjectSP obj = Dispatch("get_register_context", error); + + if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj, error)) + return {}; + + return obj->GetAsString()->GetValue().str(); +} + +#endif diff --git a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedThreadPythonInterface.h b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedThreadPythonInterface.h new file mode 100644 index 000000000000..996b8d43136b --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedThreadPythonInterface.h @@ -0,0 +1,48 @@ +//===-- ScriptedThreadPythonInterface.h ------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_SCRIPTEDTHREADPYTHONINTERFACE_H +#define LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_SCRIPTEDTHREADPYTHONINTERFACE_H + +#include "lldb/Host/Config.h" + +#if LLDB_ENABLE_PYTHON + +#include "ScriptedPythonInterface.h" +#include "lldb/Interpreter/ScriptedProcessInterface.h" + +namespace lldb_private { +class ScriptedThreadPythonInterface : public ScriptedThreadInterface, + public ScriptedPythonInterface { +public: + ScriptedThreadPythonInterface(ScriptInterpreterPythonImpl &interpreter); + + StructuredData::GenericSP + CreatePluginObject(llvm::StringRef class_name, ExecutionContext &exe_ctx, + StructuredData::DictionarySP args_sp) override; + + lldb::tid_t GetThreadID() override; + + llvm::Optional<std::string> GetName() override; + + lldb::StateType GetState() override; + + llvm::Optional<std::string> GetQueue() override; + + StructuredData::DictionarySP GetStopReason() override; + + StructuredData::ArraySP GetStackFrames() override; + + StructuredData::DictionarySP GetRegisterInfo() override; + + llvm::Optional<std::string> GetRegisterContext() override; +}; +} // namespace lldb_private + +#endif // LLDB_ENABLE_PYTHON +#endif // LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_SCRIPTEDPROCESSTHREADINTERFACE_H diff --git a/contrib/llvm-project/lldb/source/Plugins/StructuredData/DarwinLog/StructuredDataDarwinLog.cpp b/contrib/llvm-project/lldb/source/Plugins/StructuredData/DarwinLog/StructuredDataDarwinLog.cpp index 87edf7789f0d..b024854f3981 100644 --- a/contrib/llvm-project/lldb/source/Plugins/StructuredData/DarwinLog/StructuredDataDarwinLog.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/StructuredData/DarwinLog/StructuredDataDarwinLog.cpp @@ -143,14 +143,9 @@ public: const char *GetLoggingModuleName() const { return "libsystem_trace.dylib"; } }; -using StructuredDataDarwinLogPropertiesSP = - std::shared_ptr<StructuredDataDarwinLogProperties>; - -static const StructuredDataDarwinLogPropertiesSP &GetGlobalProperties() { - static StructuredDataDarwinLogPropertiesSP g_settings_sp; - if (!g_settings_sp) - g_settings_sp = std::make_shared<StructuredDataDarwinLogProperties>(); - return g_settings_sp; +static StructuredDataDarwinLogProperties &GetGlobalProperties() { + static StructuredDataDarwinLogProperties g_settings; + return g_settings; } const char *const s_filter_attributes[] = { @@ -879,9 +874,9 @@ protected: process_sp->GetStructuredDataPlugin(GetDarwinLogTypeName()); stream.Printf("Availability: %s\n", plugin_sp ? "available" : "unavailable"); - ConstString plugin_name = StructuredDataDarwinLog::GetStaticPluginName(); + llvm::StringRef plugin_name = StructuredDataDarwinLog::GetStaticPluginName(); const bool enabled = - plugin_sp ? plugin_sp->GetEnabled(plugin_name) : false; + plugin_sp ? plugin_sp->GetEnabled(ConstString(plugin_name)) : false; stream.Printf("Enabled: %s\n", enabled ? "true" : "false"); } @@ -1023,7 +1018,7 @@ bool RunEnableCommand(CommandInterpreter &interpreter) { StreamString command_stream; command_stream << "plugin structured-data darwin-log enable"; - auto enable_options = GetGlobalProperties()->GetAutoEnableOptions(); + auto enable_options = GetGlobalProperties().GetAutoEnableOptions(); if (!enable_options.empty()) { command_stream << ' '; command_stream << enable_options; @@ -1054,22 +1049,6 @@ void StructuredDataDarwinLog::Terminate() { PluginManager::UnregisterPlugin(&CreateInstance); } -ConstString StructuredDataDarwinLog::GetStaticPluginName() { - static ConstString s_plugin_name("darwin-log"); - return s_plugin_name; -} - -#pragma mark - -#pragma mark PluginInterface API - -// PluginInterface API - -ConstString StructuredDataDarwinLog::GetPluginName() { - return GetStaticPluginName(); -} - -uint32_t StructuredDataDarwinLog::GetPluginVersion() { return 1; } - #pragma mark - #pragma mark StructuredDataPlugin API @@ -1220,7 +1199,7 @@ Status StructuredDataDarwinLog::GetDescription( } bool StructuredDataDarwinLog::GetEnabled(ConstString type_name) const { - if (type_name == GetStaticPluginName()) + if (type_name.GetStringRef() == GetStaticPluginName()) return m_is_enabled; else return false; @@ -1237,7 +1216,7 @@ void StructuredDataDarwinLog::ModulesDidLoad(Process &process, __FUNCTION__, process.GetUniqueID()); // Check if we should enable the darwin log support on startup/attach. - if (!GetGlobalProperties()->GetEnableOnStartup() && + if (!GetGlobalProperties().GetEnableOnStartup() && !s_is_explicitly_enabled) { // We're neither auto-enabled or explicitly enabled, so we shouldn't try to // enable here. @@ -1264,7 +1243,7 @@ void StructuredDataDarwinLog::ModulesDidLoad(Process &process, // must be loaded into the debugged process before we can try to enable // logging. const char *logging_module_cstr = - GetGlobalProperties()->GetLoggingModuleName(); + GetGlobalProperties().GetLoggingModuleName(); if (!logging_module_cstr || (logging_module_cstr[0] == 0)) { // We need this. Bail. LLDB_LOGF(log, @@ -1384,7 +1363,7 @@ void StructuredDataDarwinLog::DebuggerInitialize(Debugger &debugger) { debugger, StructuredDataDarwinLogProperties::GetSettingName())) { const bool is_global_setting = true; PluginManager::CreateSettingForStructuredDataPlugin( - debugger, GetGlobalProperties()->GetValueProperties(), + debugger, GetGlobalProperties().GetValueProperties(), ConstString("Properties for the darwin-log" " plug-in."), is_global_setting); @@ -1421,7 +1400,7 @@ Status StructuredDataDarwinLog::FilterLaunchInfo(ProcessLaunchInfo &launch_info, // If DarwinLog is not enabled (either by explicit user command or via the // auto-enable option), then we have nothing to do. - if (!GetGlobalProperties()->GetEnableOnStartup() && + if (!GetGlobalProperties().GetEnableOnStartup() && !s_is_explicitly_enabled) { // Nothing to do, DarwinLog is not enabled. return error; @@ -1617,7 +1596,7 @@ void StructuredDataDarwinLog::AddInitCompletionHook(Process &process) { // Build up the module list. FileSpecList module_spec_list; auto module_file_spec = - FileSpec(GetGlobalProperties()->GetLoggingModuleName()); + FileSpec(GetGlobalProperties().GetLoggingModuleName()); module_spec_list.Append(module_file_spec); // We aren't specifying a source file set. @@ -1638,7 +1617,7 @@ void StructuredDataDarwinLog::AddInitCompletionHook(Process &process) { LLDB_LOGF(log, "StructuredDataDarwinLog::%s() failed to set " "breakpoint in module %s, function %s (process uid %u)", - __FUNCTION__, GetGlobalProperties()->GetLoggingModuleName(), + __FUNCTION__, GetGlobalProperties().GetLoggingModuleName(), func_name, process.GetUniqueID()); return; } @@ -1649,7 +1628,7 @@ void StructuredDataDarwinLog::AddInitCompletionHook(Process &process) { LLDB_LOGF(log, "StructuredDataDarwinLog::%s() breakpoint set in module %s," "function %s (process uid %u)", - __FUNCTION__, GetGlobalProperties()->GetLoggingModuleName(), + __FUNCTION__, GetGlobalProperties().GetLoggingModuleName(), func_name, process.GetUniqueID()); } diff --git a/contrib/llvm-project/lldb/source/Plugins/StructuredData/DarwinLog/StructuredDataDarwinLog.h b/contrib/llvm-project/lldb/source/Plugins/StructuredData/DarwinLog/StructuredDataDarwinLog.h index caa94af1f30e..308fd82e9b12 100644 --- a/contrib/llvm-project/lldb/source/Plugins/StructuredData/DarwinLog/StructuredDataDarwinLog.h +++ b/contrib/llvm-project/lldb/source/Plugins/StructuredData/DarwinLog/StructuredDataDarwinLog.h @@ -30,7 +30,7 @@ public: static void Terminate(); - static ConstString GetStaticPluginName(); + static llvm::StringRef GetStaticPluginName() { return "darwin-log"; } /// Return whether the DarwinLog functionality is enabled. /// @@ -46,9 +46,7 @@ public: // PluginInterface API - ConstString GetPluginName() override; - - uint32_t GetPluginVersion() override; + llvm::StringRef GetPluginName() override { return GetStaticPluginName(); } // StructuredDataPlugin API diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.cpp b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.cpp index b815ebb3c07a..b07674af3bd9 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.cpp @@ -176,11 +176,6 @@ void SymbolFileBreakpad::Terminate() { PluginManager::UnregisterPlugin(CreateInstance); } -ConstString SymbolFileBreakpad::GetPluginNameStatic() { - static ConstString g_name("breakpad"); - return g_name; -} - uint32_t SymbolFileBreakpad::CalculateAbilities() { if (!m_objfile_sp || !llvm::isa<ObjectFileBreakpad>(*m_objfile_sp)) return 0; @@ -209,6 +204,10 @@ CompUnitSP SymbolFileBreakpad::ParseCompileUnitAtIndex(uint32_t index) { End(*m_objfile_sp); assert(Record::classify(*It) == Record::Func); ++It; // Skip FUNC record. + // Skip INLINE records. + while (It != End && Record::classify(*It) == Record::Inline) + ++It; + if (It != End) { auto record = LineRecord::parse(*It); if (record && record->FileNum < m_files->size()) @@ -224,9 +223,45 @@ CompUnitSP SymbolFileBreakpad::ParseCompileUnitAtIndex(uint32_t index) { return cu_sp; } +FunctionSP SymbolFileBreakpad::GetOrCreateFunction(CompileUnit &comp_unit) { + user_id_t id = comp_unit.GetID(); + if (FunctionSP func_sp = comp_unit.FindFunctionByUID(id)) + return func_sp; + + Log *log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_SYMBOLS); + FunctionSP func_sp; + addr_t base = GetBaseFileAddress(); + if (base == LLDB_INVALID_ADDRESS) { + LLDB_LOG(log, "Unable to fetch the base address of object file. Skipping " + "symtab population."); + return func_sp; + } + + const SectionList *list = comp_unit.GetModule()->GetSectionList(); + CompUnitData &data = m_cu_data->GetEntryRef(id).data; + LineIterator It(*m_objfile_sp, Record::Func, data.bookmark); + assert(Record::classify(*It) == Record::Func); + + if (auto record = FuncRecord::parse(*It)) { + Mangled func_name; + func_name.SetValue(ConstString(record->Name), false); + addr_t address = record->Address + base; + SectionSP section_sp = list->FindSectionContainingFileAddress(address); + if (section_sp) { + AddressRange func_range( + section_sp, address - section_sp->GetFileAddress(), record->Size); + // Use the CU's id because every CU has only one function inside. + func_sp = std::make_shared<Function>(&comp_unit, id, 0, func_name, + nullptr, func_range); + comp_unit.AddFunction(func_sp); + } + } + return func_sp; +} + size_t SymbolFileBreakpad::ParseFunctions(CompileUnit &comp_unit) { - // TODO - return 0; + std::lock_guard<std::recursive_mutex> guard(GetModuleMutex()); + return GetOrCreateFunction(comp_unit) ? 1 : 0; } bool SymbolFileBreakpad::ParseLineTable(CompileUnit &comp_unit) { @@ -251,12 +286,88 @@ bool SymbolFileBreakpad::ParseSupportFiles(CompileUnit &comp_unit, return true; } +size_t SymbolFileBreakpad::ParseBlocksRecursive(Function &func) { + std::lock_guard<std::recursive_mutex> guard(GetModuleMutex()); + CompileUnit *comp_unit = func.GetCompileUnit(); + lldbassert(comp_unit); + ParseInlineOriginRecords(); + // A vector of current each level's parent block. For example, when parsing + // "INLINE 0 ...", the current level is 0 and its parent block is the + // funciton block at index 0. + std::vector<Block *> blocks; + Block &block = func.GetBlock(false); + block.AddRange(Block::Range(0, func.GetAddressRange().GetByteSize())); + blocks.push_back(&block); + + size_t blocks_added = 0; + addr_t func_base = func.GetAddressRange().GetBaseAddress().GetOffset(); + CompUnitData &data = m_cu_data->GetEntryRef(comp_unit->GetID()).data; + LineIterator It(*m_objfile_sp, Record::Func, data.bookmark), + End(*m_objfile_sp); + ++It; // Skip the FUNC record. + size_t last_added_nest_level = 0; + while (It != End && Record::classify(*It) == Record::Inline) { + if (auto record = InlineRecord::parse(*It)) { + if (record->InlineNestLevel == 0 || + record->InlineNestLevel <= last_added_nest_level + 1) { + last_added_nest_level = record->InlineNestLevel; + BlockSP block_sp = std::make_shared<Block>(It.GetBookmark().offset); + FileSpec callsite_file; + if (record->CallSiteFileNum < m_files->size()) + callsite_file = (*m_files)[record->CallSiteFileNum]; + llvm::StringRef name; + if (record->OriginNum < m_inline_origins->size()) + name = (*m_inline_origins)[record->OriginNum]; + + Declaration callsite(callsite_file, record->CallSiteLineNum); + block_sp->SetInlinedFunctionInfo(name.str().c_str(), + /*mangled=*/nullptr, + /*decl_ptr=*/nullptr, &callsite); + for (const auto &range : record->Ranges) { + block_sp->AddRange( + Block::Range(range.first - func_base, range.second)); + } + block_sp->FinalizeRanges(); + + blocks[record->InlineNestLevel]->AddChild(block_sp); + if (record->InlineNestLevel + 1 >= blocks.size()) { + blocks.resize(blocks.size() + 1); + } + blocks[record->InlineNestLevel + 1] = block_sp.get(); + ++blocks_added; + } + } + ++It; + } + return blocks_added; +} + +void SymbolFileBreakpad::ParseInlineOriginRecords() { + if (m_inline_origins) + return; + m_inline_origins.emplace(); + + Log *log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_SYMBOLS); + for (llvm::StringRef line : lines(Record::InlineOrigin)) { + auto record = InlineOriginRecord::parse(line); + if (!record) { + LLDB_LOG(log, "Failed to parse: {0}. Skipping record.", line); + continue; + } + + if (record->Number >= m_inline_origins->size()) + m_inline_origins->resize(record->Number + 1); + (*m_inline_origins)[record->Number] = record->Name; + } +} + uint32_t SymbolFileBreakpad::ResolveSymbolContext(const Address &so_addr, SymbolContextItem resolve_scope, SymbolContext &sc) { std::lock_guard<std::recursive_mutex> guard(GetModuleMutex()); - if (!(resolve_scope & (eSymbolContextCompUnit | eSymbolContextLineEntry))) + if (!(resolve_scope & (eSymbolContextCompUnit | eSymbolContextLineEntry | + eSymbolContextFunction | eSymbolContextBlock))) return 0; ParseCUData(); @@ -274,6 +385,22 @@ SymbolFileBreakpad::ResolveSymbolContext(const Address &so_addr, } } + if (resolve_scope & (eSymbolContextFunction | eSymbolContextBlock)) { + FunctionSP func_sp = GetOrCreateFunction(*sc.comp_unit); + if (func_sp) { + sc.function = func_sp.get(); + result |= eSymbolContextFunction; + if (resolve_scope & eSymbolContextBlock) { + Block &block = func_sp->GetBlock(true); + sc.block = block.FindInnermostBlockByOffset( + so_addr.GetFileAddress() - + sc.function->GetAddressRange().GetBaseAddress().GetFileAddress()); + if (sc.block) + result |= eSymbolContextBlock; + } + } + } + return result; } @@ -296,7 +423,20 @@ void SymbolFileBreakpad::FindFunctions( ConstString name, const CompilerDeclContext &parent_decl_ctx, FunctionNameType name_type_mask, bool include_inlines, SymbolContextList &sc_list) { - // TODO + std::lock_guard<std::recursive_mutex> guard(GetModuleMutex()); + // TODO: Implement this with supported FunctionNameType. + + for (uint32_t i = 0; i < GetNumCompileUnits(); ++i) { + CompUnitSP cu_sp = GetCompileUnitAtIndex(i); + FunctionSP func_sp = GetOrCreateFunction(*cu_sp); + if (func_sp && name == func_sp->GetNameNoArguments()) { + SymbolContext sc; + sc.comp_unit = cu_sp.get(); + sc.function = func_sp.get(); + sc.module_sp = func_sp->CalculateSymbolContextModule(); + sc_list.Append(sc); + } + } } void SymbolFileBreakpad::FindFunctions(const RegularExpression ®ex, @@ -351,11 +491,6 @@ void SymbolFileBreakpad::AddSymbols(Symtab &symtab) { size.hasValue(), /*contains_linker_annotations*/ false, /*flags*/ 0); }; - for (llvm::StringRef line : lines(Record::Func)) { - if (auto record = FuncRecord::parse(line)) - add_symbol(record->Address, record->Size, record->Name); - } - for (llvm::StringRef line : lines(Record::Public)) { if (auto record = PublicRecord::parse(line)) add_symbol(record->Address, llvm::None, record->Name); @@ -727,6 +862,10 @@ void SymbolFileBreakpad::ParseLineTableAndSupportFiles(CompileUnit &cu, End(*m_objfile_sp); assert(Record::classify(*It) == Record::Func); for (++It; It != End; ++It) { + // Skip INLINE records + if (Record::classify(*It) == Record::Inline) + continue; + auto record = LineRecord::parse(*It); if (!record) break; @@ -783,3 +922,9 @@ void SymbolFileBreakpad::ParseUnwindData() { } m_unwind_data->win.Sort(); } + +uint64_t SymbolFileBreakpad::GetDebugInfoSize() { + // Breakpad files are all debug info. + return m_objfile_sp->GetByteSize(); +} + diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.h b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.h index b0a35fa11de4..bf3e25c1a63e 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.h +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.h @@ -37,9 +37,9 @@ public: static void Initialize(); static void Terminate(); static void DebuggerInitialize(Debugger &debugger) {} - static ConstString GetPluginNameStatic(); + static llvm::StringRef GetPluginNameStatic() { return "breakpad"; } - static const char *GetPluginDescriptionStatic() { + static llvm::StringRef GetPluginDescriptionStatic() { return "Breakpad debug symbol file reader."; } @@ -63,6 +63,8 @@ public: return lldb::eLanguageTypeUnknown; } + lldb::FunctionSP GetOrCreateFunction(CompileUnit &comp_unit); + size_t ParseFunctions(CompileUnit &comp_unit) override; bool ParseLineTable(CompileUnit &comp_unit) override; @@ -79,7 +81,7 @@ public: return false; } - size_t ParseBlocksRecursive(Function &func) override { return 0; } + size_t ParseBlocksRecursive(Function &func) override; void FindGlobalVariables(ConstString name, const CompilerDeclContext &parent_decl_ctx, @@ -146,8 +148,9 @@ public: GetUnwindPlan(const Address &address, const RegisterInfoResolver &resolver) override; - ConstString GetPluginName() override { return GetPluginNameStatic(); } - uint32_t GetPluginVersion() override { return 1; } + llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); } + + uint64_t GetDebugInfoSize() override; private: // A class representing a position in the breakpad file. Useful for @@ -220,11 +223,13 @@ private: UnwindPlan::Row &row); lldb::UnwindPlanSP ParseWinUnwindPlan(const Bookmark &bookmark, const RegisterInfoResolver &resolver); + void ParseInlineOriginRecords(); using CompUnitMap = RangeDataVector<lldb::addr_t, lldb::addr_t, CompUnitData>; llvm::Optional<std::vector<FileSpec>> m_files; llvm::Optional<CompUnitMap> m_cu_data; + llvm::Optional<std::vector<llvm::StringRef>> m_inline_origins; using UnwindMap = RangeDataVector<lldb::addr_t, lldb::addr_t, Bookmark>; struct UnwindData { diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.cpp b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.cpp index 60b6b726f6c0..4e09b523b778 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.cpp @@ -75,12 +75,15 @@ void AppleDWARFIndex::GetGlobalVariables( } void AppleDWARFIndex::GetGlobalVariables( - const DWARFUnit &cu, llvm::function_ref<bool(DWARFDIE die)> callback) { + DWARFUnit &cu, llvm::function_ref<bool(DWARFDIE die)> callback) { if (!m_apple_names_up) return; + lldbassert(!cu.GetSymbolFileDWARF().GetDwoNum()); + const DWARFUnit &non_skeleton_cu = cu.GetNonSkeletonUnit(); DWARFMappedHash::DIEInfoArray hash_data; - m_apple_names_up->AppendAllDIEsInRange(cu.GetOffset(), cu.GetNextUnitOffset(), + m_apple_names_up->AppendAllDIEsInRange(non_skeleton_cu.GetOffset(), + non_skeleton_cu.GetNextUnitOffset(), hash_data); DWARFMappedHash::ExtractDIEArray(hash_data, DIERefCallback(callback)); } diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.h b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.h index a7032f50e590..ef3cb5dee035 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.h +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.h @@ -39,7 +39,7 @@ public: GetGlobalVariables(const RegularExpression ®ex, llvm::function_ref<bool(DWARFDIE die)> callback) override; void - GetGlobalVariables(const DWARFUnit &cu, + GetGlobalVariables(DWARFUnit &cu, llvm::function_ref<bool(DWARFDIE die)> callback) override; void GetObjCMethods(ConstString class_name, llvm::function_ref<bool(DWARFDIE die)> callback) override; diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParser.h b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParser.h index ffe24836955f..00123a4b9216 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParser.h +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParser.h @@ -32,7 +32,8 @@ public: virtual lldb_private::Function * ParseFunctionFromDWARF(lldb_private::CompileUnit &comp_unit, - const DWARFDIE &die) = 0; + const DWARFDIE &die, + const lldb_private::AddressRange &range) = 0; virtual bool CompleteTypeFromDWARF(const DWARFDIE &die, lldb_private::Type *type, diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp index 46015f7b43b1..4ac6e165dda3 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp @@ -843,7 +843,8 @@ TypeSP DWARFASTParserClang::ParseEnum(const SymbolContext &sc, } clang_type = m_ast.CreateEnumerationType( - attrs.name.GetCString(), GetClangDeclContextContainingDIE(die, nullptr), + attrs.name.GetStringRef(), + GetClangDeclContextContainingDIE(die, nullptr), GetOwningClangModule(die), attrs.decl, enumerator_clang_type, attrs.is_scoped_enum); } else { @@ -876,6 +877,37 @@ TypeSP DWARFASTParserClang::ParseEnum(const SymbolContext &sc, return type_sp; } +static clang::CallingConv +ConvertDWARFCallingConventionToClang(const ParsedDWARFTypeAttributes &attrs) { + switch (attrs.calling_convention) { + case llvm::dwarf::DW_CC_normal: + return clang::CC_C; + case llvm::dwarf::DW_CC_BORLAND_stdcall: + return clang::CC_X86StdCall; + case llvm::dwarf::DW_CC_BORLAND_msfastcall: + return clang::CC_X86FastCall; + case llvm::dwarf::DW_CC_LLVM_vectorcall: + return clang::CC_X86VectorCall; + case llvm::dwarf::DW_CC_BORLAND_pascal: + return clang::CC_X86Pascal; + case llvm::dwarf::DW_CC_LLVM_Win64: + return clang::CC_Win64; + case llvm::dwarf::DW_CC_LLVM_X86_64SysV: + return clang::CC_X86_64SysV; + case llvm::dwarf::DW_CC_LLVM_X86RegCall: + return clang::CC_X86RegCall; + default: + break; + } + + Log *log(LogChannelDWARF::GetLogIfAny(DWARF_LOG_TYPE_COMPLETION | + DWARF_LOG_LOOKUPS)); + LLDB_LOG(log, "Unsupported DW_AT_calling_convention value: {0}", + attrs.calling_convention); + // Use the default calling convention as a fallback. + return clang::CC_C; +} + TypeSP DWARFASTParserClang::ParseSubroutine(const DWARFDIE &die, ParsedDWARFTypeAttributes &attrs) { Log *log(LogChannelDWARF::GetLogIfAny(DWARF_LOG_TYPE_COMPLETION | @@ -954,11 +986,14 @@ TypeSP DWARFASTParserClang::ParseSubroutine(const DWARFDIE &die, is_cxx_method = false; } + clang::CallingConv calling_convention = + ConvertDWARFCallingConventionToClang(attrs); + // clang_type will get the function prototype clang type after this // call CompilerType clang_type = m_ast.CreateFunctionType( return_clang_type, function_param_types.data(), - function_param_types.size(), is_variadic, type_quals); + function_param_types.size(), is_variadic, type_quals, calling_convention); if (attrs.name) { bool type_handled = false; @@ -1372,6 +1407,123 @@ TypeSP DWARFASTParserClang::ParsePointerToMemberType( return nullptr; } +void DWARFASTParserClang::ParseInheritance( + const DWARFDIE &die, const DWARFDIE &parent_die, + const CompilerType class_clang_type, const AccessType default_accessibility, + const lldb::ModuleSP &module_sp, + std::vector<std::unique_ptr<clang::CXXBaseSpecifier>> &base_classes, + ClangASTImporter::LayoutInfo &layout_info) { + + TypeSystemClang *ast = + llvm::dyn_cast_or_null<TypeSystemClang>(class_clang_type.GetTypeSystem()); + if (ast == nullptr) + return; + + // TODO: implement DW_TAG_inheritance type parsing. + DWARFAttributes attributes; + const size_t num_attributes = die.GetAttributes(attributes); + if (num_attributes == 0) + return; + + DWARFFormValue encoding_form; + AccessType accessibility = default_accessibility; + bool is_virtual = false; + bool is_base_of_class = true; + off_t member_byte_offset = 0; + + for (uint32_t i = 0; i < num_attributes; ++i) { + const dw_attr_t attr = attributes.AttributeAtIndex(i); + DWARFFormValue form_value; + if (attributes.ExtractFormValueAtIndex(i, form_value)) { + switch (attr) { + case DW_AT_type: + encoding_form = form_value; + break; + case DW_AT_data_member_location: + if (form_value.BlockData()) { + Value initialValue(0); + Value memberOffset(0); + const DWARFDataExtractor &debug_info_data = die.GetData(); + uint32_t block_length = form_value.Unsigned(); + uint32_t block_offset = + form_value.BlockData() - debug_info_data.GetDataStart(); + if (DWARFExpression::Evaluate( + nullptr, nullptr, module_sp, + DataExtractor(debug_info_data, block_offset, block_length), + die.GetCU(), eRegisterKindDWARF, &initialValue, nullptr, + memberOffset, nullptr)) { + member_byte_offset = memberOffset.ResolveValue(nullptr).UInt(); + } + } else { + // With DWARF 3 and later, if the value is an integer constant, + // this form value is the offset in bytes from the beginning of + // the containing entity. + member_byte_offset = form_value.Unsigned(); + } + break; + + case DW_AT_accessibility: + accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); + break; + + case DW_AT_virtuality: + is_virtual = form_value.Boolean(); + break; + + default: + break; + } + } + } + + Type *base_class_type = die.ResolveTypeUID(encoding_form.Reference()); + if (base_class_type == nullptr) { + module_sp->ReportError("0x%8.8x: DW_TAG_inheritance failed to " + "resolve the base class at 0x%8.8x" + " from enclosing type 0x%8.8x. \nPlease file " + "a bug and attach the file at the start of " + "this error message", + die.GetOffset(), + encoding_form.Reference().GetOffset(), + parent_die.GetOffset()); + return; + } + + CompilerType base_class_clang_type = base_class_type->GetFullCompilerType(); + assert(base_class_clang_type); + if (TypeSystemClang::IsObjCObjectOrInterfaceType(class_clang_type)) { + ast->SetObjCSuperClass(class_clang_type, base_class_clang_type); + return; + } + std::unique_ptr<clang::CXXBaseSpecifier> result = + ast->CreateBaseClassSpecifier(base_class_clang_type.GetOpaqueQualType(), + accessibility, is_virtual, + is_base_of_class); + if (!result) + return; + + base_classes.push_back(std::move(result)); + + if (is_virtual) { + // Do not specify any offset for virtual inheritance. The DWARF + // produced by clang doesn't give us a constant offset, but gives + // us a DWARF expressions that requires an actual object in memory. + // the DW_AT_data_member_location for a virtual base class looks + // like: + // DW_AT_data_member_location( DW_OP_dup, DW_OP_deref, + // DW_OP_constu(0x00000018), DW_OP_minus, DW_OP_deref, + // DW_OP_plus ) + // Given this, there is really no valid response we can give to + // clang for virtual base class offsets, and this should eventually + // be removed from LayoutRecordType() in the external + // AST source in clang. + } else { + layout_info.base_offsets.insert(std::make_pair( + ast->GetAsCXXRecordDecl(base_class_clang_type.GetOpaqueQualType()), + clang::CharUnits::fromQuantity(member_byte_offset))); + } +} + TypeSP DWARFASTParserClang::UpdateSymbolContextScopeForType( const SymbolContext &sc, const DWARFDIE &die, TypeSP type_sp) { if (!type_sp) @@ -1584,6 +1736,7 @@ DWARFASTParserClang::ParseStructureLikeDIE(const SymbolContext &sc, } } assert(tag_decl_kind != -1); + (void)tag_decl_kind; bool clang_type_was_created = false; clang_type.SetCompilerType( &m_ast, dwarf->GetForwardDeclDieToClangType().lookup(die.GetDIE())); @@ -1763,11 +1916,10 @@ public: const CompilerType &property_opaque_type, // The property type is only // required if you don't have an // ivar decl - clang::ObjCIvarDecl *ivar_decl, const char *property_setter_name, - const char *property_getter_name, uint32_t property_attributes, - const ClangASTMetadata *metadata) + const char *property_setter_name, const char *property_getter_name, + uint32_t property_attributes, const ClangASTMetadata *metadata) : m_class_opaque_type(class_opaque_type), m_property_name(property_name), - m_property_opaque_type(property_opaque_type), m_ivar_decl(ivar_decl), + m_property_opaque_type(property_opaque_type), m_property_setter_name(property_setter_name), m_property_getter_name(property_getter_name), m_property_attributes(property_attributes) { @@ -1786,7 +1938,6 @@ public: m_class_opaque_type = rhs.m_class_opaque_type; m_property_name = rhs.m_property_name; m_property_opaque_type = rhs.m_property_opaque_type; - m_ivar_decl = rhs.m_ivar_decl; m_property_setter_name = rhs.m_property_setter_name; m_property_getter_name = rhs.m_property_getter_name; m_property_attributes = rhs.m_property_attributes; @@ -1801,7 +1952,7 @@ public: bool Finalize() { return TypeSystemClang::AddObjCClassProperty( m_class_opaque_type, m_property_name, m_property_opaque_type, - m_ivar_decl, m_property_setter_name, m_property_getter_name, + /*ivar_decl=*/nullptr, m_property_setter_name, m_property_getter_name, m_property_attributes, m_metadata_up.get()); } @@ -1809,7 +1960,6 @@ private: CompilerType m_class_opaque_type; const char *m_property_name; CompilerType m_property_opaque_type; - clang::ObjCIvarDecl *m_ivar_decl; const char *m_property_setter_name; const char *m_property_getter_name; uint32_t m_property_attributes; @@ -1966,16 +2116,12 @@ bool DWARFASTParserClang::CompleteRecordType(const DWARFDIE &die, TypeSystemClang::StartTagDeclarationDefinition(clang_type); } - int tag_decl_kind = -1; AccessType default_accessibility = eAccessNone; if (tag == DW_TAG_structure_type) { - tag_decl_kind = clang::TTK_Struct; default_accessibility = eAccessPublic; } else if (tag == DW_TAG_union_type) { - tag_decl_kind = clang::TTK_Union; default_accessibility = eAccessPublic; } else if (tag == DW_TAG_class_type) { - tag_decl_kind = clang::TTK_Class; default_accessibility = eAccessPrivate; } @@ -1999,10 +2145,8 @@ bool DWARFASTParserClang::CompleteRecordType(const DWARFDIE &die, return true; }); - for (DelayedPropertyList::iterator pi = delayed_properties.begin(), - pe = delayed_properties.end(); - pi != pe; ++pi) - pi->Finalize(); + for (DelayedAddObjCClassProperty &property : delayed_properties) + property.Finalize(); } } @@ -2199,8 +2343,11 @@ size_t DWARFASTParserClang::ParseChildEnumerators( return enumerators_added; } -Function *DWARFASTParserClang::ParseFunctionFromDWARF(CompileUnit &comp_unit, - const DWARFDIE &die) { +Function * +DWARFASTParserClang::ParseFunctionFromDWARF(CompileUnit &comp_unit, + const DWARFDIE &die, + const AddressRange &func_range) { + assert(func_range.GetBaseAddress().IsValid()); DWARFRangeList func_ranges; const char *name = nullptr; const char *mangled = nullptr; @@ -2220,149 +2367,126 @@ Function *DWARFASTParserClang::ParseFunctionFromDWARF(CompileUnit &comp_unit, if (die.GetDIENamesAndRanges(name, mangled, func_ranges, decl_file, decl_line, decl_column, call_file, call_line, call_column, &frame_base)) { + Mangled func_name; + if (mangled) + func_name.SetValue(ConstString(mangled), true); + else if ((die.GetParent().Tag() == DW_TAG_compile_unit || + die.GetParent().Tag() == DW_TAG_partial_unit) && + Language::LanguageIsCPlusPlus( + SymbolFileDWARF::GetLanguage(*die.GetCU())) && + !Language::LanguageIsObjC( + SymbolFileDWARF::GetLanguage(*die.GetCU())) && + name && strcmp(name, "main") != 0) { + // If the mangled name is not present in the DWARF, generate the + // demangled name using the decl context. We skip if the function is + // "main" as its name is never mangled. + bool is_static = false; + bool is_variadic = false; + bool has_template_params = false; + unsigned type_quals = 0; + std::vector<CompilerType> param_types; + std::vector<clang::ParmVarDecl *> param_decls; + StreamString sstr; + + DWARFDeclContext decl_ctx = SymbolFileDWARF::GetDWARFDeclContext(die); + sstr << decl_ctx.GetQualifiedName(); - // Union of all ranges in the function DIE (if the function is - // discontiguous) - AddressRange func_range; - lldb::addr_t lowest_func_addr = func_ranges.GetMinRangeBase(0); - lldb::addr_t highest_func_addr = func_ranges.GetMaxRangeEnd(0); - if (lowest_func_addr != LLDB_INVALID_ADDRESS && - lowest_func_addr <= highest_func_addr) { - ModuleSP module_sp(die.GetModule()); - func_range.GetBaseAddress().ResolveAddressUsingFileSections( - lowest_func_addr, module_sp->GetSectionList()); - if (func_range.GetBaseAddress().IsValid()) - func_range.SetByteSize(highest_func_addr - lowest_func_addr); - } - - if (func_range.GetBaseAddress().IsValid()) { - Mangled func_name; - if (mangled) - func_name.SetValue(ConstString(mangled), true); - else if ((die.GetParent().Tag() == DW_TAG_compile_unit || - die.GetParent().Tag() == DW_TAG_partial_unit) && - Language::LanguageIsCPlusPlus( - SymbolFileDWARF::GetLanguage(*die.GetCU())) && - !Language::LanguageIsObjC( - SymbolFileDWARF::GetLanguage(*die.GetCU())) && - name && strcmp(name, "main") != 0) { - // If the mangled name is not present in the DWARF, generate the - // demangled name using the decl context. We skip if the function is - // "main" as its name is never mangled. - bool is_static = false; - bool is_variadic = false; - bool has_template_params = false; - unsigned type_quals = 0; - std::vector<CompilerType> param_types; - std::vector<clang::ParmVarDecl *> param_decls; - StreamString sstr; - - DWARFDeclContext decl_ctx = SymbolFileDWARF::GetDWARFDeclContext(die); - sstr << decl_ctx.GetQualifiedName(); - - clang::DeclContext *containing_decl_ctx = - GetClangDeclContextContainingDIE(die, nullptr); - ParseChildParameters(containing_decl_ctx, die, true, is_static, - is_variadic, has_template_params, param_types, - param_decls, type_quals); - sstr << "("; - for (size_t i = 0; i < param_types.size(); i++) { - if (i > 0) - sstr << ", "; - sstr << param_types[i].GetTypeName(); - } - if (is_variadic) - sstr << ", ..."; - sstr << ")"; - if (type_quals & clang::Qualifiers::Const) - sstr << " const"; - - func_name.SetValue(ConstString(sstr.GetString()), false); - } else - func_name.SetValue(ConstString(name), false); - - FunctionSP func_sp; - std::unique_ptr<Declaration> decl_up; - if (decl_file != 0 || decl_line != 0 || decl_column != 0) - decl_up = std::make_unique<Declaration>(die.GetCU()->GetFile(decl_file), - decl_line, decl_column); - - SymbolFileDWARF *dwarf = die.GetDWARF(); - // Supply the type _only_ if it has already been parsed - Type *func_type = dwarf->GetDIEToType().lookup(die.GetDIE()); - - assert(func_type == nullptr || func_type != DIE_IS_BEING_PARSED); - - if (dwarf->FixupAddress(func_range.GetBaseAddress())) { - const user_id_t func_user_id = die.GetID(); - func_sp = - std::make_shared<Function>(&comp_unit, + clang::DeclContext *containing_decl_ctx = + GetClangDeclContextContainingDIE(die, nullptr); + ParseChildParameters(containing_decl_ctx, die, true, is_static, + is_variadic, has_template_params, param_types, + param_decls, type_quals); + sstr << "("; + for (size_t i = 0; i < param_types.size(); i++) { + if (i > 0) + sstr << ", "; + sstr << param_types[i].GetTypeName(); + } + if (is_variadic) + sstr << ", ..."; + sstr << ")"; + if (type_quals & clang::Qualifiers::Const) + sstr << " const"; + + func_name.SetValue(ConstString(sstr.GetString()), false); + } else + func_name.SetValue(ConstString(name), false); + + FunctionSP func_sp; + std::unique_ptr<Declaration> decl_up; + if (decl_file != 0 || decl_line != 0 || decl_column != 0) + decl_up = std::make_unique<Declaration>(die.GetCU()->GetFile(decl_file), + decl_line, decl_column); + + SymbolFileDWARF *dwarf = die.GetDWARF(); + // Supply the type _only_ if it has already been parsed + Type *func_type = dwarf->GetDIEToType().lookup(die.GetDIE()); + + assert(func_type == nullptr || func_type != DIE_IS_BEING_PARSED); + + const user_id_t func_user_id = die.GetID(); + func_sp = + std::make_shared<Function>(&comp_unit, func_user_id, // UserID is the DIE offset func_user_id, func_name, func_type, - func_range); // first address range + func_range); // first address range - if (func_sp.get() != nullptr) { - if (frame_base.IsValid()) - func_sp->GetFrameBaseExpression() = frame_base; - comp_unit.AddFunction(func_sp); - return func_sp.get(); - } - } + if (func_sp.get() != nullptr) { + if (frame_base.IsValid()) + func_sp->GetFrameBaseExpression() = frame_base; + comp_unit.AddFunction(func_sp); + return func_sp.get(); } } return nullptr; } -void DWARFASTParserClang::ParseSingleMember( - const DWARFDIE &die, const DWARFDIE &parent_die, - const lldb_private::CompilerType &class_clang_type, - lldb::AccessType default_accessibility, - DelayedPropertyList &delayed_properties, - lldb_private::ClangASTImporter::LayoutInfo &layout_info, - FieldInfo &last_field_info) { - ModuleSP module_sp = parent_die.GetDWARF()->GetObjectFile()->GetModule(); - const dw_tag_t tag = die.Tag(); - // Get the parent byte size so we can verify any members will fit - const uint64_t parent_byte_size = - parent_die.GetAttributeValueAsUnsigned(DW_AT_byte_size, UINT64_MAX); - const uint64_t parent_bit_size = - parent_byte_size == UINT64_MAX ? UINT64_MAX : parent_byte_size * 8; - - DWARFAttributes attributes; - const size_t num_attributes = die.GetAttributes(attributes); - if (num_attributes == 0) - return; - +namespace { +/// Parsed form of all attributes that are relevant for parsing type members. +struct MemberAttributes { + explicit MemberAttributes(const DWARFDIE &die, const DWARFDIE &parent_die, + ModuleSP module_sp); const char *name = nullptr; + /// Indicates how many bits into the word (according to the host endianness) + /// the low-order bit of the field starts. Can be negative. + int64_t bit_offset = 0; + /// Indicates the size of the field in bits. + size_t bit_size = 0; + uint64_t data_bit_offset = UINT64_MAX; + AccessType accessibility = eAccessNone; + llvm::Optional<uint64_t> byte_size; + DWARFFormValue encoding_form; + /// Indicates the byte offset of the word from the base address of the + /// structure. + uint32_t member_byte_offset; + bool is_artificial = false; + /// On DW_TAG_members, this means the member is static. + bool is_external = false; +}; + +/// Parsed form of all attributes that are relevant for parsing Objective-C +/// properties. +struct PropertyAttributes { + explicit PropertyAttributes(const DWARFDIE &die); const char *prop_name = nullptr; const char *prop_getter_name = nullptr; const char *prop_setter_name = nullptr; + /// \see clang::ObjCPropertyAttribute uint32_t prop_attributes = 0; +}; +} // namespace - bool is_artificial = false; - DWARFFormValue encoding_form; - AccessType accessibility = eAccessNone; - uint32_t member_byte_offset = - (parent_die.Tag() == DW_TAG_union_type) ? 0 : UINT32_MAX; - llvm::Optional<uint64_t> byte_size; - int64_t bit_offset = 0; - uint64_t data_bit_offset = UINT64_MAX; - size_t bit_size = 0; - bool is_external = - false; // On DW_TAG_members, this means the member is static - uint32_t i; - for (i = 0; i < num_attributes && !is_artificial; ++i) { +MemberAttributes::MemberAttributes(const DWARFDIE &die, + const DWARFDIE &parent_die, + ModuleSP module_sp) { + member_byte_offset = (parent_die.Tag() == DW_TAG_union_type) ? 0 : UINT32_MAX; + + DWARFAttributes attributes; + const size_t num_attributes = die.GetAttributes(attributes); + for (std::size_t i = 0; i < num_attributes; ++i) { const dw_attr_t attr = attributes.AttributeAtIndex(i); DWARFFormValue form_value; if (attributes.ExtractFormValueAtIndex(i, form_value)) { - // DW_AT_data_member_location indicates the byte offset of the - // word from the base address of the structure. - // - // DW_AT_bit_offset indicates how many bits into the word - // (according to the host endianness) the low-order bit of the - // field starts. AT_bit_offset can be negative. - // - // DW_AT_bit_size indicates the size of the field in bits. switch (attr) { case DW_AT_name: name = form_value.AsCString(); @@ -2413,6 +2537,42 @@ void DWARFASTParserClang::ParseSingleMember( case DW_AT_artificial: is_artificial = form_value.Boolean(); break; + case DW_AT_external: + is_external = form_value.Boolean(); + break; + default: + break; + } + } + } + + // Clang has a DWARF generation bug where sometimes it represents + // fields that are references with bad byte size and bit size/offset + // information such as: + // + // DW_AT_byte_size( 0x00 ) + // DW_AT_bit_size( 0x40 ) + // DW_AT_bit_offset( 0xffffffffffffffc0 ) + // + // So check the bit offset to make sure it is sane, and if the values + // are not sane, remove them. If we don't do this then we will end up + // with a crash if we try to use this type in an expression when clang + // becomes unhappy with its recycled debug info. + if (byte_size.getValueOr(0) == 0 && bit_offset < 0) { + bit_size = 0; + bit_offset = 0; + } +} + +PropertyAttributes::PropertyAttributes(const DWARFDIE &die) { + + DWARFAttributes attributes; + const size_t num_attributes = die.GetAttributes(attributes); + for (size_t i = 0; i < num_attributes; ++i) { + const dw_attr_t attr = attributes.AttributeAtIndex(i); + DWARFFormValue form_value; + if (attributes.ExtractFormValueAtIndex(i, form_value)) { + switch (attr) { case DW_AT_APPLE_property_name: prop_name = form_value.AsCString(); break; @@ -2425,315 +2585,330 @@ void DWARFASTParserClang::ParseSingleMember( case DW_AT_APPLE_property_attribute: prop_attributes = form_value.Unsigned(); break; - case DW_AT_external: - is_external = form_value.Boolean(); - break; - default: - case DW_AT_declaration: - case DW_AT_description: - case DW_AT_mutable: - case DW_AT_visibility: - case DW_AT_sibling: break; } } } - if (prop_name) { - ConstString fixed_setter; + if (!prop_name) + return; + ConstString fixed_setter; - // Check if the property getter/setter were provided as full names. - // We want basenames, so we extract them. + // Check if the property getter/setter were provided as full names. + // We want basenames, so we extract them. + if (prop_getter_name && prop_getter_name[0] == '-') { + ObjCLanguage::MethodName prop_getter_method(prop_getter_name, true); + prop_getter_name = prop_getter_method.GetSelector().GetCString(); + } - if (prop_getter_name && prop_getter_name[0] == '-') { - ObjCLanguage::MethodName prop_getter_method(prop_getter_name, true); - prop_getter_name = prop_getter_method.GetSelector().GetCString(); - } + if (prop_setter_name && prop_setter_name[0] == '-') { + ObjCLanguage::MethodName prop_setter_method(prop_setter_name, true); + prop_setter_name = prop_setter_method.GetSelector().GetCString(); + } - if (prop_setter_name && prop_setter_name[0] == '-') { - ObjCLanguage::MethodName prop_setter_method(prop_setter_name, true); - prop_setter_name = prop_setter_method.GetSelector().GetCString(); - } + // If the names haven't been provided, they need to be filled in. + if (!prop_getter_name) + prop_getter_name = prop_name; + if (!prop_setter_name && prop_name[0] && + !(prop_attributes & DW_APPLE_PROPERTY_readonly)) { + StreamString ss; - // If the names haven't been provided, they need to be filled in. + ss.Printf("set%c%s:", toupper(prop_name[0]), &prop_name[1]); - if (!prop_getter_name) { - prop_getter_name = prop_name; - } - if (!prop_setter_name && prop_name[0] && - !(prop_attributes & DW_APPLE_PROPERTY_readonly)) { - StreamString ss; + fixed_setter.SetString(ss.GetString()); + prop_setter_name = fixed_setter.GetCString(); + } +} - ss.Printf("set%c%s:", toupper(prop_name[0]), &prop_name[1]); +void DWARFASTParserClang::ParseObjCProperty( + const DWARFDIE &die, const DWARFDIE &parent_die, + const lldb_private::CompilerType &class_clang_type, + DelayedPropertyList &delayed_properties) { + // This function can only parse DW_TAG_APPLE_property. + assert(die.Tag() == DW_TAG_APPLE_property); - fixed_setter.SetString(ss.GetString()); - prop_setter_name = fixed_setter.GetCString(); - } - } + ModuleSP module_sp = parent_die.GetDWARF()->GetObjectFile()->GetModule(); - // Clang has a DWARF generation bug where sometimes it represents - // fields that are references with bad byte size and bit size/offset - // information such as: - // - // DW_AT_byte_size( 0x00 ) - // DW_AT_bit_size( 0x40 ) - // DW_AT_bit_offset( 0xffffffffffffffc0 ) - // - // So check the bit offset to make sure it is sane, and if the values - // are not sane, remove them. If we don't do this then we will end up - // with a crash if we try to use this type in an expression when clang - // becomes unhappy with its recycled debug info. + const MemberAttributes attrs(die, parent_die, module_sp); + const PropertyAttributes propAttrs(die); - if (byte_size.getValueOr(0) == 0 && bit_offset < 0) { - bit_size = 0; - bit_offset = 0; + if (!propAttrs.prop_name) { + module_sp->ReportError( + "0x%8.8" PRIx64 ": DW_TAG_APPLE_property has no name.", die.GetID()); + return; + } + + Type *member_type = die.ResolveTypeUID(attrs.encoding_form.Reference()); + if (!member_type) { + module_sp->ReportError("0x%8.8" PRIx64 + ": DW_TAG_APPLE_property '%s' refers to type 0x%8.8x" + " which was unable to be parsed", + die.GetID(), propAttrs.prop_name, + attrs.encoding_form.Reference().GetOffset()); + return; } + ClangASTMetadata metadata; + metadata.SetUserID(die.GetID()); + delayed_properties.push_back(DelayedAddObjCClassProperty( + class_clang_type, propAttrs.prop_name, + member_type->GetLayoutCompilerType(), propAttrs.prop_setter_name, + propAttrs.prop_getter_name, propAttrs.prop_attributes, &metadata)); +} + +void DWARFASTParserClang::ParseSingleMember( + const DWARFDIE &die, const DWARFDIE &parent_die, + const lldb_private::CompilerType &class_clang_type, + lldb::AccessType default_accessibility, + lldb_private::ClangASTImporter::LayoutInfo &layout_info, + FieldInfo &last_field_info) { + // This function can only parse DW_TAG_member. + assert(die.Tag() == DW_TAG_member); + + ModuleSP module_sp = parent_die.GetDWARF()->GetObjectFile()->GetModule(); + const dw_tag_t tag = die.Tag(); + // Get the parent byte size so we can verify any members will fit + const uint64_t parent_byte_size = + parent_die.GetAttributeValueAsUnsigned(DW_AT_byte_size, UINT64_MAX); + const uint64_t parent_bit_size = + parent_byte_size == UINT64_MAX ? UINT64_MAX : parent_byte_size * 8; + + // FIXME: Remove the workarounds below and make this const. + MemberAttributes attrs(die, parent_die, module_sp); + const bool class_is_objc_object_or_interface = TypeSystemClang::IsObjCObjectOrInterfaceType(class_clang_type); // FIXME: Make Clang ignore Objective-C accessibility for expressions if (class_is_objc_object_or_interface) - accessibility = eAccessNone; + attrs.accessibility = eAccessNone; // Handle static members - if (is_external && member_byte_offset == UINT32_MAX) { - Type *var_type = die.ResolveTypeUID(encoding_form.Reference()); + if (attrs.is_external && attrs.member_byte_offset == UINT32_MAX) { + Type *var_type = die.ResolveTypeUID(attrs.encoding_form.Reference()); if (var_type) { - if (accessibility == eAccessNone) - accessibility = eAccessPublic; + if (attrs.accessibility == eAccessNone) + attrs.accessibility = eAccessPublic; TypeSystemClang::AddVariableToRecordType( - class_clang_type, name, var_type->GetForwardCompilerType(), - accessibility); + class_clang_type, attrs.name, var_type->GetForwardCompilerType(), + attrs.accessibility); } return; } - if (!is_artificial) { - Type *member_type = die.ResolveTypeUID(encoding_form.Reference()); - - clang::FieldDecl *field_decl = nullptr; - const uint64_t character_width = 8; - const uint64_t word_width = 32; - if (tag == DW_TAG_member) { - if (member_type) { - CompilerType member_clang_type = member_type->GetLayoutCompilerType(); - - if (accessibility == eAccessNone) - accessibility = default_accessibility; - - uint64_t field_bit_offset = - (member_byte_offset == UINT32_MAX ? 0 : (member_byte_offset * 8)); - - if (bit_size > 0) { - FieldInfo this_field_info; - this_field_info.bit_offset = field_bit_offset; - this_field_info.bit_size = bit_size; + Type *member_type = die.ResolveTypeUID(attrs.encoding_form.Reference()); + if (!member_type) { + if (attrs.name) + module_sp->ReportError( + "0x%8.8" PRIx64 ": DW_TAG_member '%s' refers to type 0x%8.8x" + " which was unable to be parsed", + die.GetID(), attrs.name, attrs.encoding_form.Reference().GetOffset()); + else + module_sp->ReportError( + "0x%8.8" PRIx64 ": DW_TAG_member refers to type 0x%8.8x" + " which was unable to be parsed", + die.GetID(), attrs.encoding_form.Reference().GetOffset()); + return; + } - if (data_bit_offset != UINT64_MAX) { - this_field_info.bit_offset = data_bit_offset; - } else { - if (!byte_size) - byte_size = member_type->GetByteSize(nullptr); + const uint64_t character_width = 8; + const uint64_t word_width = 32; + CompilerType member_clang_type = member_type->GetLayoutCompilerType(); - ObjectFile *objfile = die.GetDWARF()->GetObjectFile(); - if (objfile->GetByteOrder() == eByteOrderLittle) { - this_field_info.bit_offset += byte_size.getValueOr(0) * 8; - this_field_info.bit_offset -= (bit_offset + bit_size); - } else { - this_field_info.bit_offset += bit_offset; - } - } + if (attrs.accessibility == eAccessNone) + attrs.accessibility = default_accessibility; - // The ObjC runtime knows the byte offset but we still need to provide - // the bit-offset in the layout. It just means something different then - // what it does in C and C++. So we skip this check for ObjC types. - // - // We also skip this for fields of a union since they will all have a - // zero offset. - if (!TypeSystemClang::IsObjCObjectOrInterfaceType(class_clang_type) && - !(parent_die.Tag() == DW_TAG_union_type && this_field_info.bit_offset == 0) && - ((this_field_info.bit_offset >= parent_bit_size) || - (last_field_info.IsBitfield() && - !last_field_info.NextBitfieldOffsetIsValid( - this_field_info.bit_offset)))) { - ObjectFile *objfile = die.GetDWARF()->GetObjectFile(); - objfile->GetModule()->ReportWarning( - "0x%8.8" PRIx64 ": %s bitfield named \"%s\" has invalid " - "bit offset (0x%8.8" PRIx64 - ") member will be ignored. Please file a bug against the " - "compiler and include the preprocessed output for %s\n", - die.GetID(), DW_TAG_value_to_name(tag), name, - this_field_info.bit_offset, GetUnitName(parent_die).c_str()); - return; - } + uint64_t field_bit_offset = (attrs.member_byte_offset == UINT32_MAX + ? 0 + : (attrs.member_byte_offset * 8)); - // Update the field bit offset we will report for layout - field_bit_offset = this_field_info.bit_offset; + if (attrs.bit_size > 0) { + FieldInfo this_field_info; + this_field_info.bit_offset = field_bit_offset; + this_field_info.bit_size = attrs.bit_size; - // Objective-C has invalid DW_AT_bit_offset values in older - // versions of clang, so we have to be careful and only insert - // unnamed bitfields if we have a new enough clang. - bool detect_unnamed_bitfields = true; + if (attrs.data_bit_offset != UINT64_MAX) { + this_field_info.bit_offset = attrs.data_bit_offset; + } else { + if (!attrs.byte_size) + attrs.byte_size = member_type->GetByteSize(nullptr); - if (class_is_objc_object_or_interface) - detect_unnamed_bitfields = - die.GetCU()->Supports_unnamed_objc_bitfields(); + ObjectFile *objfile = die.GetDWARF()->GetObjectFile(); + if (objfile->GetByteOrder() == eByteOrderLittle) { + this_field_info.bit_offset += attrs.byte_size.getValueOr(0) * 8; + this_field_info.bit_offset -= (attrs.bit_offset + attrs.bit_size); + } else { + this_field_info.bit_offset += attrs.bit_offset; + } + } - if (detect_unnamed_bitfields) { - clang::Optional<FieldInfo> unnamed_field_info; - uint64_t last_field_end = 0; + // The ObjC runtime knows the byte offset but we still need to provide + // the bit-offset in the layout. It just means something different then + // what it does in C and C++. So we skip this check for ObjC types. + // + // We also skip this for fields of a union since they will all have a + // zero offset. + if (!TypeSystemClang::IsObjCObjectOrInterfaceType(class_clang_type) && + !(parent_die.Tag() == DW_TAG_union_type && + this_field_info.bit_offset == 0) && + ((this_field_info.bit_offset >= parent_bit_size) || + (last_field_info.IsBitfield() && + !last_field_info.NextBitfieldOffsetIsValid( + this_field_info.bit_offset)))) { + ObjectFile *objfile = die.GetDWARF()->GetObjectFile(); + objfile->GetModule()->ReportWarning( + "0x%8.8" PRIx64 ": %s bitfield named \"%s\" has invalid " + "bit offset (0x%8.8" PRIx64 + ") member will be ignored. Please file a bug against the " + "compiler and include the preprocessed output for %s\n", + die.GetID(), DW_TAG_value_to_name(tag), attrs.name, + this_field_info.bit_offset, GetUnitName(parent_die).c_str()); + return; + } - last_field_end = - last_field_info.bit_offset + last_field_info.bit_size; + // Update the field bit offset we will report for layout + field_bit_offset = this_field_info.bit_offset; - if (!last_field_info.IsBitfield()) { - // The last field was not a bit-field... - // but if it did take up the entire word then we need to extend - // last_field_end so the bit-field does not step into the last - // fields padding. - if (last_field_end != 0 && ((last_field_end % word_width) != 0)) - last_field_end += word_width - (last_field_end % word_width); - } + // Objective-C has invalid DW_AT_bit_offset values in older + // versions of clang, so we have to be careful and only insert + // unnamed bitfields if we have a new enough clang. + bool detect_unnamed_bitfields = true; - // If we have a gap between the last_field_end and the current - // field we have an unnamed bit-field. - // If we have a base class, we assume there is no unnamed - // bit-field if this is the first field since the gap can be - // attributed to the members from the base class. This assumption - // is not correct if the first field of the derived class is - // indeed an unnamed bit-field. We currently do not have the - // machinary to track the offset of the last field of classes we - // have seen before, so we are not handling this case. - if (this_field_info.bit_offset != last_field_end && - this_field_info.bit_offset > last_field_end && - !(last_field_info.bit_offset == 0 && - last_field_info.bit_size == 0 && - layout_info.base_offsets.size() != 0)) { - unnamed_field_info = FieldInfo{}; - unnamed_field_info->bit_size = - this_field_info.bit_offset - last_field_end; - unnamed_field_info->bit_offset = last_field_end; - } + if (class_is_objc_object_or_interface) + detect_unnamed_bitfields = + die.GetCU()->Supports_unnamed_objc_bitfields(); - if (unnamed_field_info) { - clang::FieldDecl *unnamed_bitfield_decl = - TypeSystemClang::AddFieldToRecordType( - class_clang_type, llvm::StringRef(), - m_ast.GetBuiltinTypeForEncodingAndBitSize(eEncodingSint, - word_width), - accessibility, unnamed_field_info->bit_size); + if (detect_unnamed_bitfields) { + llvm::Optional<FieldInfo> unnamed_field_info; + uint64_t last_field_end = 0; - layout_info.field_offsets.insert(std::make_pair( - unnamed_bitfield_decl, unnamed_field_info->bit_offset)); - } - } + last_field_end = last_field_info.bit_offset + last_field_info.bit_size; - last_field_info = this_field_info; - last_field_info.SetIsBitfield(true); - } else { - last_field_info.bit_offset = field_bit_offset; + if (!last_field_info.IsBitfield()) { + // The last field was not a bit-field... + // but if it did take up the entire word then we need to extend + // last_field_end so the bit-field does not step into the last + // fields padding. + if (last_field_end != 0 && ((last_field_end % word_width) != 0)) + last_field_end += word_width - (last_field_end % word_width); + } - if (llvm::Optional<uint64_t> clang_type_size = - member_type->GetByteSize(nullptr)) { - last_field_info.bit_size = *clang_type_size * character_width; - } + // If we have a gap between the last_field_end and the current + // field we have an unnamed bit-field. + // If we have a base class, we assume there is no unnamed + // bit-field if this is the first field since the gap can be + // attributed to the members from the base class. This assumption + // is not correct if the first field of the derived class is + // indeed an unnamed bit-field. We currently do not have the + // machinary to track the offset of the last field of classes we + // have seen before, so we are not handling this case. + if (this_field_info.bit_offset != last_field_end && + this_field_info.bit_offset > last_field_end && + !(last_field_info.bit_offset == 0 && + last_field_info.bit_size == 0 && + layout_info.base_offsets.size() != 0)) { + unnamed_field_info = FieldInfo{}; + unnamed_field_info->bit_size = + this_field_info.bit_offset - last_field_end; + unnamed_field_info->bit_offset = last_field_end; + } - last_field_info.SetIsBitfield(false); - } + if (unnamed_field_info) { + clang::FieldDecl *unnamed_bitfield_decl = + TypeSystemClang::AddFieldToRecordType( + class_clang_type, llvm::StringRef(), + m_ast.GetBuiltinTypeForEncodingAndBitSize(eEncodingSint, + word_width), + attrs.accessibility, unnamed_field_info->bit_size); - if (!member_clang_type.IsCompleteType()) - member_clang_type.GetCompleteType(); - - { - // Older versions of clang emit array[0] and array[1] in the - // same way (<rdar://problem/12566646>). If the current field - // is at the end of the structure, then there is definitely no - // room for extra elements and we override the type to - // array[0]. - - CompilerType member_array_element_type; - uint64_t member_array_size; - bool member_array_is_incomplete; - - if (member_clang_type.IsArrayType(&member_array_element_type, - &member_array_size, - &member_array_is_incomplete) && - !member_array_is_incomplete) { - uint64_t parent_byte_size = - parent_die.GetAttributeValueAsUnsigned(DW_AT_byte_size, - UINT64_MAX); - - if (member_byte_offset >= parent_byte_size) { - if (member_array_size != 1 && - (member_array_size != 0 || - member_byte_offset > parent_byte_size)) { - module_sp->ReportError( - "0x%8.8" PRIx64 - ": DW_TAG_member '%s' refers to type 0x%8.8x" - " which extends beyond the bounds of 0x%8.8" PRIx64, - die.GetID(), name, encoding_form.Reference().GetOffset(), - parent_die.GetID()); - } + layout_info.field_offsets.insert(std::make_pair( + unnamed_bitfield_decl, unnamed_field_info->bit_offset)); + } + } - member_clang_type = - m_ast.CreateArrayType(member_array_element_type, 0, false); - } - } - } + last_field_info = this_field_info; + last_field_info.SetIsBitfield(true); + } else { + last_field_info.bit_offset = field_bit_offset; - RequireCompleteType(member_clang_type); + if (llvm::Optional<uint64_t> clang_type_size = + member_type->GetByteSize(nullptr)) { + last_field_info.bit_size = *clang_type_size * character_width; + } - field_decl = TypeSystemClang::AddFieldToRecordType( - class_clang_type, name, member_clang_type, accessibility, - bit_size); + last_field_info.SetIsBitfield(false); + } - m_ast.SetMetadataAsUserID(field_decl, die.GetID()); + // Don't turn artificial members such as vtable pointers into real FieldDecls + // in our AST. Clang will re-create those articial members and they would + // otherwise just overlap in the layout with the FieldDecls we add here. + // This needs to be done after updating FieldInfo which keeps track of where + // field start/end so we don't later try to fill the the space of this + // artificial member with (unnamed bitfield) padding. + // FIXME: This check should verify that this is indeed an artificial member + // we are supposed to ignore. + if (attrs.is_artificial) + return; - layout_info.field_offsets.insert( - std::make_pair(field_decl, field_bit_offset)); - } else { - if (name) + if (!member_clang_type.IsCompleteType()) + member_clang_type.GetCompleteType(); + + { + // Older versions of clang emit array[0] and array[1] in the + // same way (<rdar://problem/12566646>). If the current field + // is at the end of the structure, then there is definitely no + // room for extra elements and we override the type to + // array[0]. + + CompilerType member_array_element_type; + uint64_t member_array_size; + bool member_array_is_incomplete; + + if (member_clang_type.IsArrayType(&member_array_element_type, + &member_array_size, + &member_array_is_incomplete) && + !member_array_is_incomplete) { + uint64_t parent_byte_size = + parent_die.GetAttributeValueAsUnsigned(DW_AT_byte_size, UINT64_MAX); + + if (attrs.member_byte_offset >= parent_byte_size) { + if (member_array_size != 1 && + (member_array_size != 0 || + attrs.member_byte_offset > parent_byte_size)) { module_sp->ReportError( "0x%8.8" PRIx64 ": DW_TAG_member '%s' refers to type 0x%8.8x" - " which was unable to be parsed", - die.GetID(), name, encoding_form.Reference().GetOffset()); - else - module_sp->ReportError( - "0x%8.8" PRIx64 ": DW_TAG_member refers to type 0x%8.8x" - " which was unable to be parsed", - die.GetID(), encoding_form.Reference().GetOffset()); + " which extends beyond the bounds of 0x%8.8" PRIx64, + die.GetID(), attrs.name, + attrs.encoding_form.Reference().GetOffset(), + parent_die.GetID()); + } + + member_clang_type = + m_ast.CreateArrayType(member_array_element_type, 0, false); } } + } - if (prop_name != nullptr && member_type) { - clang::ObjCIvarDecl *ivar_decl = nullptr; + RequireCompleteType(member_clang_type); - if (field_decl) { - ivar_decl = clang::dyn_cast<clang::ObjCIvarDecl>(field_decl); - assert(ivar_decl != nullptr); - } + clang::FieldDecl *field_decl = TypeSystemClang::AddFieldToRecordType( + class_clang_type, attrs.name, member_clang_type, attrs.accessibility, + attrs.bit_size); - ClangASTMetadata metadata; - metadata.SetUserID(die.GetID()); - delayed_properties.push_back(DelayedAddObjCClassProperty( - class_clang_type, prop_name, member_type->GetLayoutCompilerType(), - ivar_decl, prop_setter_name, prop_getter_name, prop_attributes, - &metadata)); + m_ast.SetMetadataAsUserID(field_decl, die.GetID()); - if (ivar_decl) - m_ast.SetMetadataAsUserID(ivar_decl, die.GetID()); - } - } + layout_info.field_offsets.insert( + std::make_pair(field_decl, field_bit_offset)); } bool DWARFASTParserClang::ParseChildMembers( const DWARFDIE &parent_die, CompilerType &class_clang_type, std::vector<std::unique_ptr<clang::CXXBaseSpecifier>> &base_classes, std::vector<DWARFDIE> &member_function_dies, - DelayedPropertyList &delayed_properties, AccessType &default_accessibility, + DelayedPropertyList &delayed_properties, + const AccessType default_accessibility, ClangASTImporter::LayoutInfo &layout_info) { if (!parent_die) return false; @@ -2750,11 +2925,13 @@ bool DWARFASTParserClang::ParseChildMembers( dw_tag_t tag = die.Tag(); switch (tag) { - case DW_TAG_member: case DW_TAG_APPLE_property: + ParseObjCProperty(die, parent_die, class_clang_type, delayed_properties); + break; + + case DW_TAG_member: ParseSingleMember(die, parent_die, class_clang_type, - default_accessibility, delayed_properties, layout_info, - last_field_info); + default_accessibility, layout_info, last_field_info); break; case DW_TAG_subprogram: @@ -2762,117 +2939,10 @@ bool DWARFASTParserClang::ParseChildMembers( member_function_dies.push_back(die); break; - case DW_TAG_inheritance: { - // TODO: implement DW_TAG_inheritance type parsing - DWARFAttributes attributes; - const size_t num_attributes = die.GetAttributes(attributes); - if (num_attributes > 0) { - DWARFFormValue encoding_form; - AccessType accessibility = default_accessibility; - bool is_virtual = false; - bool is_base_of_class = true; - off_t member_byte_offset = 0; - uint32_t i; - for (i = 0; i < num_attributes; ++i) { - const dw_attr_t attr = attributes.AttributeAtIndex(i); - DWARFFormValue form_value; - if (attributes.ExtractFormValueAtIndex(i, form_value)) { - switch (attr) { - case DW_AT_type: - encoding_form = form_value; - break; - case DW_AT_data_member_location: - if (form_value.BlockData()) { - Value initialValue(0); - Value memberOffset(0); - const DWARFDataExtractor &debug_info_data = die.GetData(); - uint32_t block_length = form_value.Unsigned(); - uint32_t block_offset = - form_value.BlockData() - debug_info_data.GetDataStart(); - if (DWARFExpression::Evaluate( - nullptr, nullptr, module_sp, - DataExtractor(debug_info_data, block_offset, - block_length), - die.GetCU(), eRegisterKindDWARF, &initialValue, nullptr, - memberOffset, nullptr)) { - member_byte_offset = - memberOffset.ResolveValue(nullptr).UInt(); - } - } else { - // With DWARF 3 and later, if the value is an integer constant, - // this form value is the offset in bytes from the beginning of - // the containing entity. - member_byte_offset = form_value.Unsigned(); - } - break; - - case DW_AT_accessibility: - accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); - break; - - case DW_AT_virtuality: - is_virtual = form_value.Boolean(); - break; - - case DW_AT_sibling: - break; - - default: - break; - } - } - } - - Type *base_class_type = die.ResolveTypeUID(encoding_form.Reference()); - if (base_class_type == nullptr) { - module_sp->ReportError("0x%8.8x: DW_TAG_inheritance failed to " - "resolve the base class at 0x%8.8x" - " from enclosing type 0x%8.8x. \nPlease file " - "a bug and attach the file at the start of " - "this error message", - die.GetOffset(), - encoding_form.Reference().GetOffset(), - parent_die.GetOffset()); - break; - } - - CompilerType base_class_clang_type = - base_class_type->GetFullCompilerType(); - assert(base_class_clang_type); - if (TypeSystemClang::IsObjCObjectOrInterfaceType(class_clang_type)) { - ast->SetObjCSuperClass(class_clang_type, base_class_clang_type); - } else { - std::unique_ptr<clang::CXXBaseSpecifier> result = - ast->CreateBaseClassSpecifier( - base_class_clang_type.GetOpaqueQualType(), accessibility, - is_virtual, is_base_of_class); - if (!result) - break; - - base_classes.push_back(std::move(result)); - - if (is_virtual) { - // Do not specify any offset for virtual inheritance. The DWARF - // produced by clang doesn't give us a constant offset, but gives - // us a DWARF expressions that requires an actual object in memory. - // the DW_AT_data_member_location for a virtual base class looks - // like: - // DW_AT_data_member_location( DW_OP_dup, DW_OP_deref, - // DW_OP_constu(0x00000018), DW_OP_minus, DW_OP_deref, - // DW_OP_plus ) - // Given this, there is really no valid response we can give to - // clang for virtual base class offsets, and this should eventually - // be removed from LayoutRecordType() in the external - // AST source in clang. - } else { - layout_info.base_offsets.insert(std::make_pair( - ast->GetAsCXXRecordDecl( - base_class_clang_type.GetOpaqueQualType()), - clang::CharUnits::fromQuantity(member_byte_offset))); - } - } - } - } break; + case DW_TAG_inheritance: + ParseInheritance(die, parent_die, class_clang_type, default_accessibility, + module_sp, base_classes, layout_info); + break; default: break; @@ -3140,7 +3210,6 @@ clang::Decl *DWARFASTParserClang::GetClangDeclForDIE(const DWARFDIE &die) { if (DWARFDIE spec_die = die.GetReferencedDIE(DW_AT_specification)) { clang::Decl *decl = GetClangDeclForDIE(spec_die); m_die_to_decl[die.GetDIE()] = decl; - m_decl_to_die[decl].insert(die.GetDIE()); return decl; } @@ -3148,7 +3217,6 @@ clang::Decl *DWARFASTParserClang::GetClangDeclForDIE(const DWARFDIE &die) { die.GetReferencedDIE(DW_AT_abstract_origin)) { clang::Decl *decl = GetClangDeclForDIE(abstract_origin_die); m_die_to_decl[die.GetDIE()] = decl; - m_decl_to_die[decl].insert(die.GetDIE()); return decl; } @@ -3213,7 +3281,6 @@ clang::Decl *DWARFASTParserClang::GetClangDeclForDIE(const DWARFDIE &die) { } m_die_to_decl[die.GetDIE()] = decl; - m_decl_to_die[decl].insert(die.GetDIE()); return decl; } @@ -3477,7 +3544,8 @@ bool DWARFASTParserClang::CopyUniqueClassMethodTypes( UniqueCStringMap<DWARFDIE> dst_name_to_die; UniqueCStringMap<DWARFDIE> src_name_to_die_artificial; UniqueCStringMap<DWARFDIE> dst_name_to_die_artificial; - for (DWARFDIE src_die : src_class_die.children()) { + for (src_die = src_class_die.GetFirstChild(); src_die.IsValid(); + src_die = src_die.GetSibling()) { if (src_die.Tag() == DW_TAG_subprogram) { // Make sure this is a declaration and not a concrete instance by looking // for DW_AT_declaration set to 1. Sometimes concrete function instances @@ -3495,7 +3563,8 @@ bool DWARFASTParserClang::CopyUniqueClassMethodTypes( } } } - for (DWARFDIE dst_die : dst_class_die.children()) { + for (dst_die = dst_class_die.GetFirstChild(); dst_die.IsValid(); + dst_die = dst_die.GetSibling()) { if (dst_die.Tag() == DW_TAG_subprogram) { // Make sure this is a declaration and not a concrete instance by looking // for DW_AT_declaration set to 1. Sometimes concrete function instances diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h index 9bf6240b7554..f97c0c470ab0 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h @@ -47,7 +47,8 @@ public: lldb_private::Function * ParseFunctionFromDWARF(lldb_private::CompileUnit &comp_unit, - const DWARFDIE &die) override; + const DWARFDIE &die, + const lldb_private::AddressRange &func_range) override; bool CompleteTypeFromDWARF(const DWARFDIE &die, lldb_private::Type *type, @@ -73,7 +74,6 @@ protected: class DelayedAddObjCClassProperty; typedef std::vector<DelayedAddObjCClassProperty> DelayedPropertyList; - typedef llvm::SmallPtrSet<const DWARFDebugInfoEntry *, 4> DIEPointerSet; typedef llvm::DenseMap<const DWARFDebugInfoEntry *, clang::DeclContext *> DIEToDeclContextMap; typedef std::multimap<const clang::DeclContext *, const DWARFDIE> @@ -83,11 +83,9 @@ protected: DIEToModuleMap; typedef llvm::DenseMap<const DWARFDebugInfoEntry *, clang::Decl *> DIEToDeclMap; - typedef llvm::DenseMap<const clang::Decl *, DIEPointerSet> DeclToDIEMap; lldb_private::TypeSystemClang &m_ast; DIEToDeclMap m_die_to_decl; - DeclToDIEMap m_decl_to_die; DIEToDeclContextMap m_die_to_decl_ctx; DeclContextToDIEMap m_decl_ctx_to_die; DIEToModuleMap m_die_to_module; @@ -113,7 +111,7 @@ protected: std::vector<std::unique_ptr<clang::CXXBaseSpecifier>> &base_classes, std::vector<DWARFDIE> &member_function_dies, DelayedPropertyList &delayed_properties, - lldb::AccessType &default_accessibility, + const lldb::AccessType default_accessibility, lldb_private::ClangASTImporter::LayoutInfo &layout_info); size_t @@ -190,11 +188,26 @@ private: } }; + /// Parses a DW_TAG_APPLE_property DIE and appends the parsed data to the + /// list of delayed Objective-C properties. + /// + /// Note: The delayed property needs to be finalized to actually create the + /// property declarations in the module AST. + /// + /// \param die The DW_TAG_APPLE_property DIE that will be parsed. + /// \param parent_die The parent DIE. + /// \param class_clang_type The Objective-C class that will contain the + /// created property. + /// \param delayed_properties The list of delayed properties that the result + /// will be appended to. + void ParseObjCProperty(const DWARFDIE &die, const DWARFDIE &parent_die, + const lldb_private::CompilerType &class_clang_type, + DelayedPropertyList &delayed_properties); + void ParseSingleMember(const DWARFDIE &die, const DWARFDIE &parent_die, const lldb_private::CompilerType &class_clang_type, lldb::AccessType default_accessibility, - DelayedPropertyList &delayed_properties, lldb_private::ClangASTImporter::LayoutInfo &layout_info, FieldInfo &last_field_info); @@ -215,6 +228,28 @@ private: ParsedDWARFTypeAttributes &attrs); lldb::TypeSP ParsePointerToMemberType(const DWARFDIE &die, const ParsedDWARFTypeAttributes &attrs); + + /// Parses a DW_TAG_inheritance DIE into a base/super class. + /// + /// \param die The DW_TAG_inheritance DIE to parse. + /// \param parent_die The parent DIE of the given DIE. + /// \param class_clang_type The C++/Objective-C class representing parent_die. + /// For an Objective-C class this method sets the super class on success. For + /// a C++ class this will *not* add the result as a base class. + /// \param default_accessibility The default accessibility that is given to + /// base classes if they don't have an explicit accessibility set. + /// \param module_sp The current Module. + /// \param base_classes The list of C++ base classes that will be appended + /// with the parsed base class on success. + /// \param layout_info The layout information that will be updated for C++ + /// base classes with the base offset. + void ParseInheritance( + const DWARFDIE &die, const DWARFDIE &parent_die, + const lldb_private::CompilerType class_clang_type, + const lldb::AccessType default_accessibility, + const lldb::ModuleSP &module_sp, + std::vector<std::unique_ptr<clang::CXXBaseSpecifier>> &base_classes, + lldb_private::ClangASTImporter::LayoutInfo &layout_info); }; /// Parsed form of all attributes that are relevant for type reconstruction. diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp index dda691eecacc..529007e31b9e 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp @@ -448,3 +448,7 @@ bool DWARFDIE::GetDIENamesAndRanges( } else return false; } + +llvm::iterator_range<DWARFDIE::child_iterator> DWARFDIE::children() const { + return llvm::make_range(child_iterator(*this), child_iterator()); +} diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.h b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.h index 56154055c44d..5ee44a763204 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.h +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.h @@ -90,14 +90,9 @@ public: int &decl_line, int &decl_column, int &call_file, int &call_line, int &call_column, lldb_private::DWARFExpression *frame_base) const; + /// The range of all the children of this DIE. - /// - /// This is a template just because child_iterator is not completely defined - /// at this point. - template <typename T = child_iterator> - llvm::iterator_range<T> children() const { - return llvm::make_range(T(*this), T()); - } + llvm::iterator_range<child_iterator> children() const; }; class DWARFDIE::child_iterator diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp index e43afa104413..b72c7406ece1 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp @@ -174,15 +174,6 @@ bool DWARFDebugInfo::ContainsTypeUnits() { return !m_type_hash_to_unit_index.empty(); } -DWARFDIE -DWARFDebugInfo::GetDIEForDIEOffset(DIERef::Section section, - dw_offset_t die_offset) { - DWARFUnit *cu = GetUnitContainingDIEOffset(section, die_offset); - if (cu) - return cu->GetDIE(die_offset); - return DWARFDIE(); -} - // GetDIE() // // Get the DIE (Debug Information Entry) with the specified offset. diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.h b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.h index 46c04d749c46..c990ac9fbe58 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.h +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.h @@ -43,8 +43,6 @@ public: DWARFUnit *GetUnit(const DIERef &die_ref); DWARFTypeUnit *GetTypeUnitForHash(uint64_t hash); bool ContainsTypeUnits(); - DWARFDIE GetDIEForDIEOffset(DIERef::Section section, - dw_offset_t die_offset); DWARFDIE GetDIE(const DIERef &die_ref); enum { diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.cpp b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.cpp index 683033d0ee4c..6707d471e09b 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.cpp @@ -41,7 +41,7 @@ bool DWARFIndex::ProcessFunctionDIE( return true; // In case of a full match, we just insert everything we find. - if (name_type_mask & eFunctionNameTypeFull) + if (name_type_mask & eFunctionNameTypeFull && die.GetMangledName() == name) return callback(die); // If looking for ObjC selectors, we need to also check if the name is a diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.h b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.h index ecf82a910b66..1d3d70dfef01 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.h +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.h @@ -13,6 +13,8 @@ #include "Plugins/SymbolFile/DWARF/DWARFDIE.h" #include "Plugins/SymbolFile/DWARF/DWARFFormValue.h" +#include "lldb/Target/Statistics.h" + class DWARFDeclContext; class DWARFDIE; @@ -34,8 +36,9 @@ public: virtual void GetGlobalVariables(const RegularExpression ®ex, llvm::function_ref<bool(DWARFDIE die)> callback) = 0; + /// \a cu must be the skeleton unit if possible, not GetNonSkeletonUnit(). virtual void - GetGlobalVariables(const DWARFUnit &cu, + GetGlobalVariables(DWARFUnit &cu, llvm::function_ref<bool(DWARFDIE die)> callback) = 0; virtual void GetObjCMethods(ConstString class_name, @@ -61,8 +64,11 @@ public: virtual void Dump(Stream &s) = 0; + StatsDuration GetIndexTime() { return m_index_time; } + protected: Module &m_module; + StatsDuration m_index_time{0.0}; /// Helper function implementing common logic for processing function dies. If /// the function given by "ref" matches search criteria given by diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp index 824e43872269..5487f709d223 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp @@ -9,7 +9,6 @@ #include "DWARFUnit.h" #include "lldb/Core/Module.h" -#include "lldb/Host/StringConvert.h" #include "lldb/Symbol/ObjectFile.h" #include "lldb/Utility/LLDBAssert.h" #include "lldb/Utility/StreamString.h" @@ -35,12 +34,12 @@ DWARFUnit::DWARFUnit(SymbolFileDWARF &dwarf, lldb::user_id_t uid, DIERef::Section section, bool is_dwo) : UserID(uid), m_dwarf(dwarf), m_header(header), m_abbrevs(&abbrevs), m_cancel_scopes(false), m_section(section), m_is_dwo(is_dwo), - m_dwo_id(header.GetDWOId()) {} + m_has_parsed_non_skeleton_unit(false), m_dwo_id(header.GetDWOId()) {} DWARFUnit::~DWARFUnit() = default; -// Parses first DIE of a compile unit. -void DWARFUnit::ExtractUnitDIEIfNeeded() { +// Parses first DIE of a compile unit, excluding DWO. +void DWARFUnit::ExtractUnitDIENoDwoIfNeeded() { { llvm::sys::ScopedReader lock(m_first_die_mutex); if (m_first_die) @@ -50,7 +49,9 @@ void DWARFUnit::ExtractUnitDIEIfNeeded() { if (m_first_die) return; // Already parsed - LLDB_SCOPED_TIMERF("%8.8x: DWARFUnit::ExtractUnitDIEIfNeeded()", GetOffset()); + ElapsedTime elapsed(m_dwarf.GetDebugInfoParseTimeRef()); + LLDB_SCOPED_TIMERF("%8.8x: DWARFUnit::ExtractUnitDIENoDwoIfNeeded()", + GetOffset()); // Set the offset to that of the first DIE and calculate the start of the // next compilation unit header. @@ -66,6 +67,58 @@ void DWARFUnit::ExtractUnitDIEIfNeeded() { } } +// Parses first DIE of a compile unit including DWO. +void DWARFUnit::ExtractUnitDIEIfNeeded() { + ExtractUnitDIENoDwoIfNeeded(); + + if (m_has_parsed_non_skeleton_unit) + return; + + m_has_parsed_non_skeleton_unit = true; + + std::shared_ptr<SymbolFileDWARFDwo> dwo_symbol_file = + m_dwarf.GetDwoSymbolFileForCompileUnit(*this, m_first_die); + if (!dwo_symbol_file) + return; + + DWARFUnit *dwo_cu = dwo_symbol_file->GetDWOCompileUnitForHash(m_dwo_id); + + if (!dwo_cu) + return; // Can't fetch the compile unit from the dwo file. + dwo_cu->SetUserData(this); + + DWARFBaseDIE dwo_cu_die = dwo_cu->GetUnitDIEOnly(); + if (!dwo_cu_die.IsValid()) + return; // Can't fetch the compile unit DIE from the dwo file. + + // Here for DWO CU we want to use the address base set in the skeleton unit + // (DW_AT_addr_base) if it is available and use the DW_AT_GNU_addr_base + // otherwise. We do that because pre-DWARF v5 could use the DW_AT_GNU_* + // attributes which were applicable to the DWO units. The corresponding + // DW_AT_* attributes standardized in DWARF v5 are also applicable to the + // main unit in contrast. + if (m_addr_base) + dwo_cu->SetAddrBase(*m_addr_base); + else if (m_gnu_addr_base) + dwo_cu->SetAddrBase(*m_gnu_addr_base); + + if (GetVersion() <= 4 && m_gnu_ranges_base) + dwo_cu->SetRangesBase(*m_gnu_ranges_base); + else if (dwo_symbol_file->GetDWARFContext() + .getOrLoadRngListsData() + .GetByteSize() > 0) + dwo_cu->SetRangesBase(llvm::DWARFListTableHeader::getHeaderSize(DWARF32)); + + if (GetVersion() >= 5 && + dwo_symbol_file->GetDWARFContext().getOrLoadLocListsData().GetByteSize() > + 0) + dwo_cu->SetLoclistsBase(llvm::DWARFListTableHeader::getHeaderSize(DWARF32)); + + dwo_cu->SetBaseAddress(GetBaseAddress()); + + m_dwo = std::shared_ptr<DWARFUnit>(std::move(dwo_symbol_file), dwo_cu); +} + // Parses a compile unit and indexes its DIEs if it hasn't already been done. // It will leave this compile unit extracted forever. void DWARFUnit::ExtractDIEsIfNeeded() { @@ -144,6 +197,7 @@ DWARFUnit::ScopedExtractDIEs &DWARFUnit::ScopedExtractDIEs::operator=( void DWARFUnit::ExtractDIEsRWLocked() { llvm::sys::ScopedWriter first_die_lock(m_first_die_mutex); + ElapsedTime elapsed(m_dwarf.GetDebugInfoParseTimeRef()); LLDB_SCOPED_TIMERF("%8.8x: DWARFUnit::ExtractDIEsIfNeeded()", GetOffset()); // Set the offset to that of the first DIE and calculate the start of the @@ -291,14 +345,12 @@ void DWARFUnit::SetDwoStrOffsetsBase() { } uint64_t DWARFUnit::GetDWOId() { - ExtractUnitDIEIfNeeded(); + ExtractUnitDIENoDwoIfNeeded(); return m_dwo_id; } // m_die_array_mutex must be already held as read/write. void DWARFUnit::AddUnitDIE(const DWARFDebugInfoEntry &cu_die) { - llvm::Optional<uint64_t> addr_base, gnu_addr_base, gnu_ranges_base; - DWARFAttributes attributes; size_t num_attributes = cu_die.GetAttributes(this, attributes); @@ -308,8 +360,7 @@ void DWARFUnit::AddUnitDIE(const DWARFDebugInfoEntry &cu_die) { continue; DWARFFormValue form_value; if (attributes.ExtractFormValueAtIndex(i, form_value)) { - addr_base = form_value.Unsigned(); - SetAddrBase(*addr_base); + SetAddrBase(form_value.Unsigned()); break; } } @@ -341,10 +392,10 @@ void DWARFUnit::AddUnitDIE(const DWARFDebugInfoEntry &cu_die) { m_line_table_offset = form_value.Unsigned(); break; case DW_AT_GNU_addr_base: - gnu_addr_base = form_value.Unsigned(); + m_gnu_addr_base = form_value.Unsigned(); break; case DW_AT_GNU_ranges_base: - gnu_ranges_base = form_value.Unsigned(); + m_gnu_ranges_base = form_value.Unsigned(); break; case DW_AT_GNU_dwo_id: m_dwo_id = form_value.Unsigned(); @@ -353,50 +404,10 @@ void DWARFUnit::AddUnitDIE(const DWARFDebugInfoEntry &cu_die) { } if (m_is_dwo) { + m_has_parsed_non_skeleton_unit = true; SetDwoStrOffsetsBase(); return; } - - std::shared_ptr<SymbolFileDWARFDwo> dwo_symbol_file = - m_dwarf.GetDwoSymbolFileForCompileUnit(*this, cu_die); - if (!dwo_symbol_file) - return; - - DWARFUnit *dwo_cu = dwo_symbol_file->GetDWOCompileUnitForHash(m_dwo_id); - - if (!dwo_cu) - return; // Can't fetch the compile unit from the dwo file. - dwo_cu->SetUserData(this); - - DWARFBaseDIE dwo_cu_die = dwo_cu->GetUnitDIEOnly(); - if (!dwo_cu_die.IsValid()) - return; // Can't fetch the compile unit DIE from the dwo file. - - // Here for DWO CU we want to use the address base set in the skeleton unit - // (DW_AT_addr_base) if it is available and use the DW_AT_GNU_addr_base - // otherwise. We do that because pre-DWARF v5 could use the DW_AT_GNU_* - // attributes which were applicable to the DWO units. The corresponding - // DW_AT_* attributes standardized in DWARF v5 are also applicable to the main - // unit in contrast. - if (addr_base) - dwo_cu->SetAddrBase(*addr_base); - else if (gnu_addr_base) - dwo_cu->SetAddrBase(*gnu_addr_base); - - if (GetVersion() <= 4 && gnu_ranges_base) - dwo_cu->SetRangesBase(*gnu_ranges_base); - else if (dwo_symbol_file->GetDWARFContext() - .getOrLoadRngListsData() - .GetByteSize() > 0) - dwo_cu->SetRangesBase(llvm::DWARFListTableHeader::getHeaderSize(DWARF32)); - - if (GetVersion() >= 5 && - dwo_symbol_file->GetDWARFContext().getOrLoadLocListsData().GetByteSize() > - 0) - dwo_cu->SetLoclistsBase(llvm::DWARFListTableHeader::getHeaderSize(DWARF32)); - dwo_cu->SetBaseAddress(GetBaseAddress()); - - m_dwo = std::shared_ptr<DWARFUnit>(std::move(dwo_symbol_file), dwo_cu); } size_t DWARFUnit::GetDebugInfoSize() const { @@ -412,7 +423,7 @@ dw_offset_t DWARFUnit::GetAbbrevOffset() const { } dw_offset_t DWARFUnit::GetLineTableOffset() { - ExtractUnitDIEIfNeeded(); + ExtractUnitDIENoDwoIfNeeded(); return m_line_table_offset; } @@ -427,15 +438,20 @@ ParseListTableHeader(const llvm::DWARFDataExtractor &data, uint64_t offset, // We are expected to be called with Offset 0 or pointing just past the table // header. Correct Offset in the latter case so that it points to the start // of the header. - if (offset > 0) { - uint64_t HeaderSize = llvm::DWARFListTableHeader::getHeaderSize(format); - if (offset < HeaderSize) - return llvm::createStringError(errc::invalid_argument, - "did not detect a valid" - " list table with base = 0x%" PRIx64 "\n", - offset); - offset -= HeaderSize; + if (offset == 0) { + // This means DW_AT_rnglists_base is missing and therefore DW_FORM_rnglistx + // cannot be handled. Returning a default-constructed ListTableType allows + // DW_FORM_sec_offset to be supported. + return ListTableType(); } + + uint64_t HeaderSize = llvm::DWARFListTableHeader::getHeaderSize(format); + if (offset < HeaderSize) + return llvm::createStringError(errc::invalid_argument, + "did not detect a valid" + " list table with base = 0x%" PRIx64 "\n", + offset); + offset -= HeaderSize; ListTableType Table; if (llvm::Error E = Table.extractHeaderAndOffsets(data, &offset)) return std::move(E); @@ -443,6 +459,18 @@ ParseListTableHeader(const llvm::DWARFDataExtractor &data, uint64_t offset, } void DWARFUnit::SetLoclistsBase(dw_addr_t loclists_base) { + uint64_t offset = 0; + if (const llvm::DWARFUnitIndex::Entry *entry = m_header.GetIndexEntry()) { + const auto *contribution = entry->getContribution(llvm::DW_SECT_LOCLISTS); + if (!contribution) { + GetSymbolFileDWARF().GetObjectFile()->GetModule()->ReportError( + "Failed to find location list contribution for CU with DWO Id " + "0x%" PRIx64, + this->GetDWOId()); + return; + } + offset += contribution->Offset; + } m_loclists_base = loclists_base; uint64_t header_size = llvm::DWARFListTableHeader::getHeaderSize(DWARF32); @@ -450,13 +478,14 @@ void DWARFUnit::SetLoclistsBase(dw_addr_t loclists_base) { return; m_loclist_table_header.emplace(".debug_loclists", "locations"); - uint64_t offset = loclists_base - header_size; + offset += loclists_base - header_size; if (llvm::Error E = m_loclist_table_header->extract( m_dwarf.GetDWARFContext().getOrLoadLocListsData().GetAsLLVM(), &offset)) { GetSymbolFileDWARF().GetObjectFile()->GetModule()->ReportError( - "Failed to extract location list table at offset 0x%" PRIx64 ": %s", - loclists_base, toString(std::move(E)).c_str()); + "Failed to extract location list table at offset 0x%" PRIx64 + " (location list base: 0x%" PRIx64 "): %s", + offset, loclists_base, toString(std::move(E)).c_str()); } } @@ -476,9 +505,28 @@ DWARFDataExtractor DWARFUnit::GetLocationData() const { const DWARFDataExtractor &data = GetVersion() >= 5 ? Ctx.getOrLoadLocListsData() : Ctx.getOrLoadLocData(); if (const llvm::DWARFUnitIndex::Entry *entry = m_header.GetIndexEntry()) { - if (const auto *contribution = entry->getContribution(llvm::DW_SECT_EXT_LOC)) + if (const auto *contribution = entry->getContribution( + GetVersion() >= 5 ? llvm::DW_SECT_LOCLISTS : llvm::DW_SECT_EXT_LOC)) + return DWARFDataExtractor(data, contribution->Offset, + contribution->Length); + return DWARFDataExtractor(); + } + return data; +} + +DWARFDataExtractor DWARFUnit::GetRnglistData() const { + DWARFContext &Ctx = GetSymbolFileDWARF().GetDWARFContext(); + const DWARFDataExtractor &data = Ctx.getOrLoadRngListsData(); + if (const llvm::DWARFUnitIndex::Entry *entry = m_header.GetIndexEntry()) { + if (const auto *contribution = + entry->getContribution(llvm::DW_SECT_RNGLISTS)) return DWARFDataExtractor(data, contribution->Offset, contribution->Length); + GetSymbolFileDWARF().GetObjectFile()->GetModule()->ReportError( + "Failed to find range list contribution for CU with signature " + "0x%" PRIx64, + entry->getSignature()); + return DWARFDataExtractor(); } return data; @@ -496,8 +544,7 @@ DWARFUnit::GetRnglistTable() { m_rnglist_table_done = true; if (auto table_or_error = ParseListTableHeader<llvm::DWARFDebugRnglistTable>( - m_dwarf.GetDWARFContext().getOrLoadRngListsData().GetAsLLVM(), - m_ranges_base, DWARF32)) + GetRnglistData().GetAsLLVM(), m_ranges_base, DWARF32)) m_rnglist_table = std::move(table_or_error.get()); else GetSymbolFileDWARF().GetObjectFile()->GetModule()->ReportError( @@ -518,7 +565,7 @@ llvm::Expected<uint64_t> DWARFUnit::GetRnglistOffset(uint32_t Index) { "DW_AT_rnglists_base for CU at 0x%8.8x", GetOffset()); if (llvm::Optional<uint64_t> off = GetRnglistTable()->getOffsetEntry( - m_dwarf.GetDWARFContext().getOrLoadRngListsData().GetAsLLVM(), Index)) + GetRnglistData().GetAsLLVM(), Index)) return *off + m_ranges_base; return llvm::createStringError( errc::invalid_argument, @@ -609,52 +656,45 @@ bool DWARFUnit::DW_AT_decl_file_attributes_are_invalid() { } bool DWARFUnit::Supports_unnamed_objc_bitfields() { - if (GetProducer() == eProducerClang) { - const uint32_t major_version = GetProducerVersionMajor(); - return major_version > 425 || - (major_version == 425 && GetProducerVersionUpdate() >= 13); - } - return true; // Assume all other compilers didn't have incorrect ObjC bitfield - // info + if (GetProducer() == eProducerClang) + return GetProducerVersion() >= llvm::VersionTuple(425, 0, 13); + // Assume all other compilers didn't have incorrect ObjC bitfield info. + return true; } void DWARFUnit::ParseProducerInfo() { - m_producer_version_major = UINT32_MAX; - m_producer_version_minor = UINT32_MAX; - m_producer_version_update = UINT32_MAX; - + m_producer = eProducerOther; const DWARFDebugInfoEntry *die = GetUnitDIEPtrOnly(); - if (die) { - - const char *producer_cstr = - die->GetAttributeValueAsString(this, DW_AT_producer, nullptr); - if (producer_cstr) { - RegularExpression llvm_gcc_regex( - llvm::StringRef("^4\\.[012]\\.[01] \\(Based on Apple " - "Inc\\. build [0-9]+\\) \\(LLVM build " - "[\\.0-9]+\\)$")); - if (llvm_gcc_regex.Execute(llvm::StringRef(producer_cstr))) { - m_producer = eProducerLLVMGCC; - } else if (strstr(producer_cstr, "clang")) { - static RegularExpression g_clang_version_regex( - llvm::StringRef("clang-([0-9]+)\\.([0-9]+)\\.([0-9]+)")); - llvm::SmallVector<llvm::StringRef, 4> matches; - if (g_clang_version_regex.Execute(llvm::StringRef(producer_cstr), - &matches)) { - m_producer_version_major = - StringConvert::ToUInt32(matches[1].str().c_str(), UINT32_MAX, 10); - m_producer_version_minor = - StringConvert::ToUInt32(matches[2].str().c_str(), UINT32_MAX, 10); - m_producer_version_update = - StringConvert::ToUInt32(matches[3].str().c_str(), UINT32_MAX, 10); - } - m_producer = eProducerClang; - } else if (strstr(producer_cstr, "GNU")) - m_producer = eProducerGCC; - } + if (!die) + return; + + llvm::StringRef producer( + die->GetAttributeValueAsString(this, DW_AT_producer, nullptr)); + if (producer.empty()) + return; + + static const RegularExpression g_swiftlang_version_regex( + llvm::StringRef(R"(swiftlang-([0-9]+\.[0-9]+\.[0-9]+(\.[0-9]+)?))")); + static const RegularExpression g_clang_version_regex( + llvm::StringRef(R"(clang-([0-9]+\.[0-9]+\.[0-9]+(\.[0-9]+)?))")); + static const RegularExpression g_llvm_gcc_regex( + llvm::StringRef(R"(4\.[012]\.[01] )" + R"(\(Based on Apple Inc\. build [0-9]+\) )" + R"(\(LLVM build [\.0-9]+\)$)")); + + llvm::SmallVector<llvm::StringRef, 3> matches; + if (g_swiftlang_version_regex.Execute(producer, &matches)) { + m_producer_version.tryParse(matches[1]); + m_producer = eProducerSwift; + } else if (producer.contains("clang")) { + if (g_clang_version_regex.Execute(producer, &matches)) + m_producer_version.tryParse(matches[1]); + m_producer = eProducerClang; + } else if (producer.contains("GNU")) { + m_producer = eProducerGCC; + } else if (g_llvm_gcc_regex.Execute(producer)) { + m_producer = eProducerLLVMGCC; } - if (m_producer == eProducerInvalid) - m_producer = eProcucerOther; } DWARFProducer DWARFUnit::GetProducer() { @@ -663,22 +703,10 @@ DWARFProducer DWARFUnit::GetProducer() { return m_producer; } -uint32_t DWARFUnit::GetProducerVersionMajor() { - if (m_producer_version_major == 0) +llvm::VersionTuple DWARFUnit::GetProducerVersion() { + if (m_producer_version.empty()) ParseProducerInfo(); - return m_producer_version_major; -} - -uint32_t DWARFUnit::GetProducerVersionMinor() { - if (m_producer_version_minor == 0) - ParseProducerInfo(); - return m_producer_version_minor; -} - -uint32_t DWARFUnit::GetProducerVersionUpdate() { - if (m_producer_version_update == 0) - ParseProducerInfo(); - return m_producer_version_update; + return m_producer_version; } uint64_t DWARFUnit::GetDWARFLanguageType() { @@ -972,8 +1000,11 @@ DWARFUnit::FindRnglistFromOffset(dw_offset_t offset) { return llvm::createStringError(errc::invalid_argument, "missing or invalid range list table"); - auto range_list_or_error = GetRnglistTable()->findList( - m_dwarf.GetDWARFContext().getOrLoadRngListsData().GetAsLLVM(), offset); + llvm::DWARFDataExtractor data = GetRnglistData().GetAsLLVM(); + + // As DW_AT_rnglists_base may be missing we need to call setAddressSize. + data.setAddressSize(m_header.GetAddressByteSize()); + auto range_list_or_error = GetRnglistTable()->findList(data, offset); if (!range_list_or_error) return range_list_or_error.takeError(); diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h index da79a6aaf64e..cece29dcf9ac 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h @@ -29,7 +29,8 @@ enum DWARFProducer { eProducerClang, eProducerGCC, eProducerLLVMGCC, - eProcucerOther + eProducerSwift, + eProducerOther }; /// Base class describing the header of any kind of "unit." Some information @@ -92,6 +93,7 @@ public: uint64_t GetDWOId(); void ExtractUnitDIEIfNeeded(); + void ExtractUnitDIENoDwoIfNeeded(); void ExtractDIEsIfNeeded(); class ScopedExtractDIEs { @@ -151,7 +153,7 @@ public: const DWARFAbbreviationDeclarationSet *GetAbbreviations() const; dw_offset_t GetAbbrevOffset() const; uint8_t GetAddressByteSize() const { return m_header.GetAddressByteSize(); } - dw_addr_t GetAddrBase() const { return m_addr_base; } + dw_addr_t GetAddrBase() const { return m_addr_base ? *m_addr_base : 0; } dw_addr_t GetBaseAddress() const { return m_base_addr; } dw_offset_t GetLineTableOffset(); dw_addr_t GetRangesBase() const { return m_ranges_base; } @@ -194,11 +196,7 @@ public: DWARFProducer GetProducer(); - uint32_t GetProducerVersionMajor(); - - uint32_t GetProducerVersionMinor(); - - uint32_t GetProducerVersionUpdate(); + llvm::VersionTuple GetProducerVersion(); uint64_t GetDWARFLanguageType(); @@ -268,7 +266,7 @@ protected: // Get the DWARF unit DWARF debug information entry. Parse the single DIE // if needed. const DWARFDebugInfoEntry *GetUnitDIEPtrOnly() { - ExtractUnitDIEIfNeeded(); + ExtractUnitDIENoDwoIfNeeded(); // m_first_die_mutex is not required as m_first_die is never cleared. if (!m_first_die) return NULL; @@ -285,6 +283,8 @@ protected: const llvm::Optional<llvm::DWARFDebugRnglistTable> &GetRnglistTable(); + lldb_private::DWARFDataExtractor GetRnglistData() const; + SymbolFileDWARF &m_dwarf; std::shared_ptr<DWARFUnit> m_dwo; DWARFUnitHeader m_header; @@ -308,16 +308,16 @@ protected: std::unique_ptr<DWARFDebugAranges> m_func_aranges_up; dw_addr_t m_base_addr = 0; DWARFProducer m_producer = eProducerInvalid; - uint32_t m_producer_version_major = 0; - uint32_t m_producer_version_minor = 0; - uint32_t m_producer_version_update = 0; + llvm::VersionTuple m_producer_version; llvm::Optional<uint64_t> m_language_type; lldb_private::LazyBool m_is_optimized = lldb_private::eLazyBoolCalculate; llvm::Optional<lldb_private::FileSpec> m_comp_dir; llvm::Optional<lldb_private::FileSpec> m_file_spec; - dw_addr_t m_addr_base = 0; ///< Value of DW_AT_addr_base. - dw_addr_t m_loclists_base = 0; ///< Value of DW_AT_loclists_base. - dw_addr_t m_ranges_base = 0; ///< Value of DW_AT_rnglists_base. + llvm::Optional<dw_addr_t> m_addr_base; ///< Value of DW_AT_addr_base. + dw_addr_t m_loclists_base = 0; ///< Value of DW_AT_loclists_base. + dw_addr_t m_ranges_base = 0; ///< Value of DW_AT_rnglists_base. + llvm::Optional<uint64_t> m_gnu_addr_base; + llvm::Optional<uint64_t> m_gnu_ranges_base; /// Value of DW_AT_stmt_list. dw_offset_t m_line_table_offset = DW_INVALID_OFFSET; @@ -330,6 +330,7 @@ protected: const DIERef::Section m_section; bool m_is_dwo; + bool m_has_parsed_non_skeleton_unit; /// Value of DW_AT_GNU_dwo_id (v4) or dwo_id from CU header (v5). uint64_t m_dwo_id; diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp index cb3e662a6cdf..4a148e7744bb 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp @@ -123,8 +123,10 @@ void DebugNamesDWARFIndex::GetGlobalVariables( } void DebugNamesDWARFIndex::GetGlobalVariables( - const DWARFUnit &cu, llvm::function_ref<bool(DWARFDIE die)> callback) { + DWARFUnit &cu, llvm::function_ref<bool(DWARFDIE die)> callback) { + lldbassert(!cu.GetSymbolFileDWARF().GetDwoNum()); uint64_t cu_offset = cu.GetOffset(); + bool found_entry_for_cu = false; for (const DebugNames::NameIndex &ni: *m_debug_names_up) { for (DebugNames::NameTableEntry nte: ni) { uint64_t entry_offset = nte.getEntryOffset(); @@ -135,6 +137,7 @@ void DebugNamesDWARFIndex::GetGlobalVariables( if (entry_or->getCUOffset() != cu_offset) continue; + found_entry_for_cu = true; if (!ProcessEntry(*entry_or, callback, llvm::StringRef(nte.getString()))) return; @@ -142,8 +145,10 @@ void DebugNamesDWARFIndex::GetGlobalVariables( MaybeLogLookupError(entry_or.takeError(), ni, nte.getString()); } } - - m_fallback.GetGlobalVariables(cu, callback); + // If no name index for that particular CU was found, fallback to + // creating the manual index. + if (!found_entry_for_cu) + m_fallback.GetGlobalVariables(cu, callback); } void DebugNamesDWARFIndex::GetCompleteObjCClass( diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.h b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.h index 5d041c36c8f2..c451ccd4857f 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.h +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.h @@ -32,7 +32,7 @@ public: GetGlobalVariables(const RegularExpression ®ex, llvm::function_ref<bool(DWARFDIE die)> callback) override; void - GetGlobalVariables(const DWARFUnit &cu, + GetGlobalVariables(DWARFUnit &cu, llvm::function_ref<bool(DWARFDIE die)> callback) override; void GetObjCMethods(ConstString class_name, diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp index 1f40d880ea34..ab10e9ca98f9 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp @@ -30,6 +30,7 @@ void ManualDWARFIndex::Index() { SymbolFileDWARF &main_dwarf = *m_dwarf; m_dwarf = nullptr; + ElapsedTime elapsed(m_index_time); LLDB_SCOPED_TIMERF("%p", static_cast<void *>(&main_dwarf)); DWARFDebugInfo &main_info = main_dwarf.DebugInfo(); @@ -358,7 +359,8 @@ void ManualDWARFIndex::GetGlobalVariables( } void ManualDWARFIndex::GetGlobalVariables( - const DWARFUnit &unit, llvm::function_ref<bool(DWARFDIE die)> callback) { + DWARFUnit &unit, llvm::function_ref<bool(DWARFDIE die)> callback) { + lldbassert(!unit.GetSymbolFileDWARF().GetDwoNum()); Index(); m_set.globals.FindAllEntriesForUnit(unit, DIERefCallback(callback)); } diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.h b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.h index baff989eecca..36f371402b90 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.h +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.h @@ -33,7 +33,7 @@ public: GetGlobalVariables(const RegularExpression ®ex, llvm::function_ref<bool(DWARFDIE die)> callback) override; void - GetGlobalVariables(const DWARFUnit &unit, + GetGlobalVariables(DWARFUnit &unit, llvm::function_ref<bool(DWARFDIE die)> callback) override; void GetObjCMethods(ConstString class_name, llvm::function_ref<bool(DWARFDIE die)> callback) override; diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/NameToDIE.cpp b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/NameToDIE.cpp index 42e96af84a96..493d1b4a2702 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/NameToDIE.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/NameToDIE.cpp @@ -45,15 +45,16 @@ bool NameToDIE::Find(const RegularExpression ®ex, } void NameToDIE::FindAllEntriesForUnit( - const DWARFUnit &unit, - llvm::function_ref<bool(DIERef ref)> callback) const { + DWARFUnit &s_unit, llvm::function_ref<bool(DIERef ref)> callback) const { + lldbassert(!s_unit.GetSymbolFileDWARF().GetDwoNum()); + const DWARFUnit &ns_unit = s_unit.GetNonSkeletonUnit(); const uint32_t size = m_map.GetSize(); for (uint32_t i = 0; i < size; ++i) { const DIERef &die_ref = m_map.GetValueAtIndexUnchecked(i); - if (unit.GetSymbolFileDWARF().GetDwoNum() == die_ref.dwo_num() && - unit.GetDebugSection() == die_ref.section() && - unit.GetOffset() <= die_ref.die_offset() && - die_ref.die_offset() < unit.GetNextUnitOffset()) { + if (ns_unit.GetSymbolFileDWARF().GetDwoNum() == die_ref.dwo_num() && + ns_unit.GetDebugSection() == die_ref.section() && + ns_unit.GetOffset() <= die_ref.die_offset() && + die_ref.die_offset() < ns_unit.GetNextUnitOffset()) { if (!callback(die_ref)) return; } diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/NameToDIE.h b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/NameToDIE.h index a6863f6c9549..994af07189f8 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/NameToDIE.h +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/NameToDIE.h @@ -38,8 +38,9 @@ public: bool Find(const lldb_private::RegularExpression ®ex, llvm::function_ref<bool(DIERef ref)> callback) const; + /// \a unit must be the skeleton unit if possible, not GetNonSkeletonUnit(). void - FindAllEntriesForUnit(const DWARFUnit &unit, + FindAllEntriesForUnit(DWARFUnit &unit, llvm::function_ref<bool(DIERef ref)> callback) const; void diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp index ccaf31317d75..2dd7ae60b231 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp @@ -100,24 +100,6 @@ LLDB_PLUGIN_DEFINE(SymbolFileDWARF) char SymbolFileDWARF::ID; -// static inline bool -// child_requires_parent_class_union_or_struct_to_be_completed (dw_tag_t tag) -//{ -// switch (tag) -// { -// default: -// break; -// case DW_TAG_subprogram: -// case DW_TAG_inlined_subroutine: -// case DW_TAG_class_type: -// case DW_TAG_structure_type: -// case DW_TAG_union_type: -// return true; -// } -// return false; -//} -// - namespace { #define LLDB_PROPERTIES_symbolfiledwarf @@ -131,7 +113,7 @@ enum { class PluginProperties : public Properties { public: static ConstString GetSettingName() { - return SymbolFileDWARF::GetPluginNameStatic(); + return ConstString(SymbolFileDWARF::GetPluginNameStatic()); } PluginProperties() { @@ -145,11 +127,9 @@ public: } }; -typedef std::shared_ptr<PluginProperties> SymbolFileDWARFPropertiesSP; - -static const SymbolFileDWARFPropertiesSP &GetGlobalPluginProperties() { - static const auto g_settings_sp(std::make_shared<PluginProperties>()); - return g_settings_sp; +static PluginProperties &GetGlobalPluginProperties() { + static PluginProperties g_settings; + return g_settings; } } // namespace @@ -267,7 +247,7 @@ void SymbolFileDWARF::DebuggerInitialize(Debugger &debugger) { debugger, PluginProperties::GetSettingName())) { const bool is_global_setting = true; PluginManager::CreateSettingForSymbolFilePlugin( - debugger, GetGlobalPluginProperties()->GetValueProperties(), + debugger, GetGlobalPluginProperties().GetValueProperties(), ConstString("Properties for the dwarf symbol-file plug-in."), is_global_setting); } @@ -279,12 +259,7 @@ void SymbolFileDWARF::Terminate() { LogChannelDWARF::Terminate(); } -lldb_private::ConstString SymbolFileDWARF::GetPluginNameStatic() { - static ConstString g_name("dwarf"); - return g_name; -} - -const char *SymbolFileDWARF::GetPluginDescriptionStatic() { +llvm::StringRef SymbolFileDWARF::GetPluginDescriptionStatic() { return "DWARF and DWARF3 debug symbol file reader."; } @@ -470,7 +445,9 @@ SymbolFileDWARF::GetTypeSystemForLanguage(LanguageType language) { void SymbolFileDWARF::InitializeObject() { Log *log = LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO); - if (!GetGlobalPluginProperties()->IgnoreFileIndexes()) { + InitializeFirstCodeAddress(); + + if (!GetGlobalPluginProperties().IgnoreFileIndexes()) { StreamString module_desc; GetObjectFile()->GetModule()->GetDescription(module_desc.AsRawOstream(), lldb::eDescriptionLevelBrief); @@ -514,6 +491,25 @@ void SymbolFileDWARF::InitializeObject() { std::make_unique<ManualDWARFIndex>(*GetObjectFile()->GetModule(), *this); } +void SymbolFileDWARF::InitializeFirstCodeAddress() { + InitializeFirstCodeAddressRecursive( + *m_objfile_sp->GetModule()->GetSectionList()); + if (m_first_code_address == LLDB_INVALID_ADDRESS) + m_first_code_address = 0; +} + +void SymbolFileDWARF::InitializeFirstCodeAddressRecursive( + const lldb_private::SectionList §ion_list) { + for (SectionSP section_sp : section_list) { + if (section_sp->GetChildren().GetSize() > 0) { + InitializeFirstCodeAddressRecursive(section_sp->GetChildren()); + } else if (section_sp->GetType() == eSectionTypeCode) { + m_first_code_address = + std::min(m_first_code_address, section_sp->GetFileAddress()); + } + } +} + bool SymbolFileDWARF::SupportedVersion(uint16_t version) { return version >= 2 && version <= 5; } @@ -687,6 +683,17 @@ static void MakeAbsoluteAndRemap(FileSpec &file_spec, DWARFUnit &dwarf_cu, file_spec.SetFile(*remapped_file, FileSpec::Style::native); } +/// Return the DW_AT_(GNU_)dwo_name. +static const char *GetDWOName(DWARFCompileUnit &dwarf_cu, + const DWARFDebugInfoEntry &cu_die) { + const char *dwo_name = + cu_die.GetAttributeValueAsString(&dwarf_cu, DW_AT_GNU_dwo_name, nullptr); + if (!dwo_name) + dwo_name = + cu_die.GetAttributeValueAsString(&dwarf_cu, DW_AT_dwo_name, nullptr); + return dwo_name; +} + lldb::CompUnitSP SymbolFileDWARF::ParseCompileUnit(DWARFCompileUnit &dwarf_cu) { CompUnitSP cu_sp; CompileUnit *comp_unit = (CompileUnit *)dwarf_cu.GetUserData(); @@ -701,25 +708,66 @@ lldb::CompUnitSP SymbolFileDWARF::ParseCompileUnit(DWARFCompileUnit &dwarf_cu) { } else { ModuleSP module_sp(m_objfile_sp->GetModule()); if (module_sp) { - const DWARFBaseDIE cu_die = - dwarf_cu.GetNonSkeletonUnit().GetUnitDIEOnly(); - if (cu_die) { - FileSpec cu_file_spec(cu_die.GetName(), dwarf_cu.GetPathStyle()); - MakeAbsoluteAndRemap(cu_file_spec, dwarf_cu, module_sp); - - LanguageType cu_language = SymbolFileDWARF::LanguageTypeFromDWARF( - cu_die.GetAttributeValueAsUnsigned(DW_AT_language, 0)); - - bool is_optimized = dwarf_cu.GetNonSkeletonUnit().GetIsOptimized(); + auto initialize_cu = [&](const FileSpec &file_spec, + LanguageType cu_language) { BuildCuTranslationTable(); cu_sp = std::make_shared<CompileUnit>( - module_sp, &dwarf_cu, cu_file_spec, + module_sp, &dwarf_cu, file_spec, *GetDWARFUnitIndex(dwarf_cu.GetID()), cu_language, - is_optimized ? eLazyBoolYes : eLazyBoolNo); + eLazyBoolCalculate); dwarf_cu.SetUserData(cu_sp.get()); SetCompileUnitAtIndex(dwarf_cu.GetID(), cu_sp); + }; + + auto lazy_initialize_cu = [&]() { + // If the version is < 5, we can't do lazy initialization. + if (dwarf_cu.GetVersion() < 5) + return false; + + // If there is no DWO, there is no reason to initialize + // lazily; we will do eager initialization in that case. + if (GetDebugMapSymfile()) + return false; + const DWARFBaseDIE cu_die = dwarf_cu.GetUnitDIEOnly(); + if (!cu_die) + return false; + if (!GetDWOName(dwarf_cu, *cu_die.GetDIE())) + return false; + + // With DWARFv5 we can assume that the first support + // file is also the name of the compile unit. This + // allows us to avoid loading the non-skeleton unit, + // which may be in a separate DWO file. + FileSpecList support_files; + if (!ParseSupportFiles(dwarf_cu, module_sp, support_files)) + return false; + if (support_files.GetSize() == 0) + return false; + + initialize_cu(support_files.GetFileSpecAtIndex(0), + eLanguageTypeUnknown); + cu_sp->SetSupportFiles(std::move(support_files)); + return true; + }; + + if (!lazy_initialize_cu()) { + // Eagerly initialize compile unit + const DWARFBaseDIE cu_die = + dwarf_cu.GetNonSkeletonUnit().GetUnitDIEOnly(); + if (cu_die) { + LanguageType cu_language = SymbolFileDWARF::LanguageTypeFromDWARF( + dwarf_cu.GetDWARFLanguageType()); + + FileSpec cu_file_spec(cu_die.GetName(), dwarf_cu.GetPathStyle()); + + // Path needs to be remapped in this case. In the support files + // case ParseSupportFiles takes care of the remapping. + MakeAbsoluteAndRemap(cu_file_spec, dwarf_cu, module_sp); + + initialize_cu(cu_file_spec, cu_language); + } } } } @@ -785,7 +833,32 @@ Function *SymbolFileDWARF::ParseFunction(CompileUnit &comp_unit, if (!dwarf_ast) return nullptr; - return dwarf_ast->ParseFunctionFromDWARF(comp_unit, die); + DWARFRangeList ranges; + if (die.GetDIE()->GetAttributeAddressRanges(die.GetCU(), ranges, + /*check_hi_lo_pc=*/true) == 0) + return nullptr; + + // Union of all ranges in the function DIE (if the function is + // discontiguous) + lldb::addr_t lowest_func_addr = ranges.GetMinRangeBase(0); + lldb::addr_t highest_func_addr = ranges.GetMaxRangeEnd(0); + if (lowest_func_addr == LLDB_INVALID_ADDRESS || + lowest_func_addr >= highest_func_addr || + lowest_func_addr < m_first_code_address) + return nullptr; + + ModuleSP module_sp(die.GetModule()); + AddressRange func_range; + func_range.GetBaseAddress().ResolveAddressUsingFileSections( + lowest_func_addr, module_sp->GetSectionList()); + if (!func_range.GetBaseAddress().IsValid()) + return nullptr; + + func_range.SetByteSize(highest_func_addr - lowest_func_addr); + if (!FixupAddress(func_range.GetBaseAddress())) + return nullptr; + + return dwarf_ast->ParseFunctionFromDWARF(comp_unit, die, func_range); } lldb::addr_t SymbolFileDWARF::FixupAddress(lldb::addr_t file_addr) { @@ -807,7 +880,7 @@ lldb::LanguageType SymbolFileDWARF::ParseLanguage(CompileUnit &comp_unit) { std::lock_guard<std::recursive_mutex> guard(GetModuleMutex()); DWARFUnit *dwarf_cu = GetDWARFCompileUnit(&comp_unit); if (dwarf_cu) - return GetLanguage(*dwarf_cu); + return GetLanguage(dwarf_cu->GetNonSkeletonUnit()); else return eLanguageTypeUnknown; } @@ -898,18 +971,30 @@ bool SymbolFileDWARF::ParseSupportFiles(CompileUnit &comp_unit, if (!dwarf_cu) return false; - dw_offset_t offset = dwarf_cu->GetLineTableOffset(); + if (!ParseSupportFiles(*dwarf_cu, comp_unit.GetModule(), support_files)) + return false; + + comp_unit.SetSupportFiles(support_files); + return true; +} + +bool SymbolFileDWARF::ParseSupportFiles(DWARFUnit &dwarf_cu, + const ModuleSP &module, + FileSpecList &support_files) { + + dw_offset_t offset = dwarf_cu.GetLineTableOffset(); if (offset == DW_INVALID_OFFSET) return false; + ElapsedTime elapsed(m_parse_time); llvm::DWARFDebugLine::Prologue prologue; if (!ParseLLVMLineTablePrologue(m_context, prologue, offset, - dwarf_cu->GetOffset())) + dwarf_cu.GetOffset())) return false; - comp_unit.SetSupportFiles(ParseSupportFilesFromPrologue( - comp_unit.GetModule(), prologue, dwarf_cu->GetPathStyle(), - dwarf_cu->GetCompilationDirectory().GetCString())); + support_files = ParseSupportFilesFromPrologue( + module, prologue, dwarf_cu.GetPathStyle(), + dwarf_cu.GetCompilationDirectory().GetCString()); return true; } @@ -950,6 +1035,7 @@ SymbolFileDWARF::GetTypeUnitSupportFiles(DWARFTypeUnit &tu) { "SymbolFileDWARF::GetTypeUnitSupportFiles failed to parse " "the line table prologue"); }; + ElapsedTime elapsed(m_parse_time); llvm::Error error = prologue.parse(data, &line_table_offset, report, ctx); if (error) { report(std::move(error)); @@ -965,7 +1051,7 @@ bool SymbolFileDWARF::ParseIsOptimized(CompileUnit &comp_unit) { std::lock_guard<std::recursive_mutex> guard(GetModuleMutex()); DWARFUnit *dwarf_cu = GetDWARFCompileUnit(&comp_unit); if (dwarf_cu) - return dwarf_cu->GetIsOptimized(); + return dwarf_cu->GetNonSkeletonUnit().GetIsOptimized(); return false; } @@ -1036,6 +1122,7 @@ bool SymbolFileDWARF::ParseLineTable(CompileUnit &comp_unit) { if (offset == DW_INVALID_OFFSET) return false; + ElapsedTime elapsed(m_parse_time); llvm::DWARFDebugLine line; const llvm::DWARFDebugLine::LineTable *line_table = ParseLLVMLineTable(m_context, line, offset, dwarf_cu->GetOffset()); @@ -1050,6 +1137,12 @@ bool SymbolFileDWARF::ParseLineTable(CompileUnit &comp_unit) { // The Sequences view contains only valid line sequences. Don't iterate over // the Rows directly. for (const llvm::DWARFDebugLine::Sequence &seq : line_table->Sequences) { + // Ignore line sequences that do not start after the first code address. + // All addresses generated in a sequence are incremental so we only need + // to check the first one of the sequence. Check the comment at the + // m_first_code_address declaration for more details on this. + if (seq.LowPC < m_first_code_address) + continue; std::unique_ptr<LineSequence> sequence = LineTable::CreateLineSequenceContainer(); for (unsigned idx = seq.FirstRowIndex; idx < seq.LastRowIndex; ++idx) { @@ -1084,6 +1177,7 @@ SymbolFileDWARF::ParseDebugMacros(lldb::offset_t *offset) { if (iter != m_debug_macros_map.end()) return iter->second; + ElapsedTime elapsed(m_parse_time); const DWARFDataExtractor &debug_macro_data = m_context.getOrLoadMacroData(); if (debug_macro_data.GetByteSize() == 0) return DebugMacrosSP(); @@ -1585,17 +1679,6 @@ SymbolFileDWARF::GetDIE(const DIERef &die_ref) { return DebugInfo().GetDIE(die_ref); } -/// Return the DW_AT_(GNU_)dwo_name. -static const char *GetDWOName(DWARFCompileUnit &dwarf_cu, - const DWARFDebugInfoEntry &cu_die) { - const char *dwo_name = - cu_die.GetAttributeValueAsString(&dwarf_cu, DW_AT_GNU_dwo_name, nullptr); - if (!dwo_name) - dwo_name = - cu_die.GetAttributeValueAsString(&dwarf_cu, DW_AT_dwo_name, nullptr); - return dwo_name; -} - /// Return the DW_AT_(GNU_)dwo_id. /// FIXME: Technically 0 is a valid hash. static uint64_t GetDWOId(DWARFCompileUnit &dwarf_cu, @@ -1623,7 +1706,7 @@ SymbolFileDWARF::GetDwoSymbolFileForCompileUnit( DWARFUnit &unit, const DWARFDebugInfoEntry &cu_die) { // If this is a Darwin-style debug map (non-.dSYM) symbol file, // never attempt to load ELF-style DWO files since the -gmodules - // support uses the same DWO machanism to specify full debug info + // support uses the same DWO mechanism to specify full debug info // files for modules. This is handled in // UpdateExternalModuleListIfNeeded(). if (GetDebugMapSymfile()) @@ -2083,7 +2166,7 @@ void SymbolFileDWARF::FindGlobalVariables( } } - ParseVariables(sc, die, LLDB_INVALID_ADDRESS, false, false, &variables); + ParseAndAppendGlobalVariable(sc, die, variables); while (pruned_idx < variables.GetSize()) { VariableSP var_sp = variables.GetVariableAtIndex(pruned_idx); if (name_is_mangled || @@ -2136,7 +2219,7 @@ void SymbolFileDWARF::FindGlobalVariables(const RegularExpression ®ex, return true; sc.comp_unit = GetCompUnitForDWARFCompUnit(*dwarf_cu); - ParseVariables(sc, die, LLDB_INVALID_ADDRESS, false, false, &variables); + ParseAndAppendGlobalVariable(sc, die, variables); return variables.GetSize() - original_size < max_matches; }); @@ -2186,13 +2269,8 @@ bool SymbolFileDWARF::ResolveFunction(const DWARFDIE &orig_die, addr = sc.function->GetAddressRange().GetBaseAddress(); } - - if (auto section_sp = addr.GetSection()) { - if (section_sp->GetPermissions() & ePermissionsExecutable) { - sc_list.Append(sc); - return true; - } - } + sc_list.Append(sc); + return true; } return false; @@ -2507,7 +2585,7 @@ TypeSP SymbolFileDWARF::GetTypeForDIE(const DWARFDIE &die, type_sp = ParseType(sc, die, nullptr); } else if (type_ptr != DIE_IS_BEING_PARSED) { - // Grab the existing type from the master types lists + // Get the original shared pointer for this type type_sp = type_ptr->shared_from_this(); } } @@ -2793,7 +2871,7 @@ TypeSP SymbolFileDWARF::FindDefinitionTypeForDWARFDeclContext( } m_index->GetTypes(dwarf_decl_ctx, [&](DWARFDIE type_die) { - // Make sure type_die's langauge matches the type system we are + // Make sure type_die's language matches the type system we are // looking for. We don't want to find a "Foo" type from Java if we // are looking for a "Foo" type for C, C++, ObjC, or ObjC++. if (type_system && @@ -2997,8 +3075,8 @@ size_t SymbolFileDWARF::ParseVariablesForContext(const SymbolContext &sc) { /*check_hi_lo_pc=*/true)) func_lo_pc = ranges.GetMinRangeBase(0); if (func_lo_pc != LLDB_INVALID_ADDRESS) { - const size_t num_variables = ParseVariables( - sc, function_die.GetFirstChild(), func_lo_pc, true, true); + const size_t num_variables = + ParseVariablesInFunctionContext(sc, function_die, func_lo_pc); // Let all blocks know they have parse all their variables sc.function->GetBlock(false).SetDidParseVariables(true, true); @@ -3017,16 +3095,14 @@ size_t SymbolFileDWARF::ParseVariablesForContext(const SymbolContext &sc) { variables = std::make_shared<VariableList>(); sc.comp_unit->SetVariableList(variables); - m_index->GetGlobalVariables( - dwarf_cu->GetNonSkeletonUnit(), [&](DWARFDIE die) { - VariableSP var_sp( - ParseVariableDIE(sc, die, LLDB_INVALID_ADDRESS)); - if (var_sp) { - variables->AddVariableIfUnique(var_sp); - ++vars_added; - } - return true; - }); + m_index->GetGlobalVariables(*dwarf_cu, [&](DWARFDIE die) { + VariableSP var_sp(ParseVariableDIECached(sc, die)); + if (var_sp) { + variables->AddVariableIfUnique(var_sp); + ++vars_added; + } + return true; + }); } return vars_added; } @@ -3034,6 +3110,26 @@ size_t SymbolFileDWARF::ParseVariablesForContext(const SymbolContext &sc) { return 0; } +VariableSP SymbolFileDWARF::ParseVariableDIECached(const SymbolContext &sc, + const DWARFDIE &die) { + if (!die) + return nullptr; + + DIEToVariableSP &die_to_variable = die.GetDWARF()->GetDIEToVariable(); + + VariableSP var_sp = die_to_variable[die.GetDIE()]; + if (var_sp) + return var_sp; + + var_sp = ParseVariableDIE(sc, die, LLDB_INVALID_ADDRESS); + if (var_sp) { + die_to_variable[die.GetDIE()] = var_sp; + if (DWARFDIE spec_die = die.GetReferencedDIE(DW_AT_specification)) + die_to_variable[spec_die.GetDIE()] = var_sp; + } + return var_sp; +} + VariableSP SymbolFileDWARF::ParseVariableDIE(const SymbolContext &sc, const DWARFDIE &die, const lldb::addr_t func_low_pc) { @@ -3043,9 +3139,6 @@ VariableSP SymbolFileDWARF::ParseVariableDIE(const SymbolContext &sc, if (!die) return nullptr; - if (VariableSP var_sp = GetDIEToVariable()[die.GetDIE()]) - return var_sp; // Already been parsed! - const dw_tag_t tag = die.Tag(); ModuleSP module = GetObjectFile()->GetModule(); @@ -3055,8 +3148,6 @@ VariableSP SymbolFileDWARF::ParseVariableDIE(const SymbolContext &sc, DWARFAttributes attributes; const size_t num_attributes = die.GetAttributes(attributes); - DWARFDIE spec_die; - VariableSP var_sp; const char *name = nullptr; const char *mangled = nullptr; Declaration decl; @@ -3103,9 +3194,6 @@ VariableSP SymbolFileDWARF::ParseVariableDIE(const SymbolContext &sc, case DW_AT_location: location_form = form_value; break; - case DW_AT_specification: - spec_die = form_value.Reference(); - break; case DW_AT_start_scope: // TODO: Implement this. break; @@ -3116,6 +3204,7 @@ VariableSP SymbolFileDWARF::ParseVariableDIE(const SymbolContext &sc, case DW_AT_description: case DW_AT_endianity: case DW_AT_segment: + case DW_AT_specification: case DW_AT_visibility: default: case DW_AT_abstract_origin: @@ -3244,7 +3333,7 @@ VariableSP SymbolFileDWARF::ParseVariableDIE(const SymbolContext &sc, SymbolFileDWARFDebugMap *debug_map_symfile = GetDebugMapSymfile(); if (debug_map_symfile) // Set the module of the expression to the linked module - // instead of the oject file so the relocated address can be + // instead of the object file so the relocated address can be // found there. location.SetModule(debug_map_symfile->GetObjectFile()->GetModule()); @@ -3308,7 +3397,7 @@ VariableSP SymbolFileDWARF::ParseVariableDIE(const SymbolContext &sc, location.Update_DW_OP_addr(exe_file_addr); } else { // Variable didn't make it into the final executable - return var_sp; + return nullptr; } } } @@ -3354,35 +3443,25 @@ VariableSP SymbolFileDWARF::ParseVariableDIE(const SymbolContext &sc, } } - if (symbol_context_scope) { - auto type_sp = std::make_shared<SymbolFileType>( - *this, GetUID(type_die_form.Reference())); - - if (use_type_size_for_value && type_sp->GetType()) - location.UpdateValue( - const_value_form.Unsigned(), - type_sp->GetType()->GetByteSize(nullptr).getValueOr(0), - die.GetCU()->GetAddressByteSize()); - - var_sp = std::make_shared<Variable>( - die.GetID(), name, mangled, type_sp, scope, symbol_context_scope, - scope_ranges, &decl, location, is_external, is_artificial, - location_is_const_value_data, is_static_member); - } else { + if (!symbol_context_scope) { // Not ready to parse this variable yet. It might be a global or static // variable that is in a function scope and the function in the symbol // context wasn't filled in yet - return var_sp; + return nullptr; } - // Cache var_sp even if NULL (the variable was just a specification or was - // missing vital information to be able to be displayed in the debugger - // (missing location due to optimization, etc)) so we don't re-parse this - // DIE over and over later... - GetDIEToVariable()[die.GetDIE()] = var_sp; - if (spec_die) - GetDIEToVariable()[spec_die.GetDIE()] = var_sp; - return var_sp; + auto type_sp = std::make_shared<SymbolFileType>( + *this, GetUID(type_die_form.Reference())); + + if (use_type_size_for_value && type_sp->GetType()) + location.UpdateValue(const_value_form.Unsigned(), + type_sp->GetType()->GetByteSize(nullptr).getValueOr(0), + die.GetCU()->GetAddressByteSize()); + + return std::make_shared<Variable>( + die.GetID(), name, mangled, type_sp, scope, symbol_context_scope, + scope_ranges, &decl, location, is_external, is_artificial, + location_is_const_value_data, is_static_member); } DWARFDIE @@ -3429,120 +3508,234 @@ SymbolFileDWARF::FindBlockContainingSpecification( return DWARFDIE(); } -size_t SymbolFileDWARF::ParseVariables(const SymbolContext &sc, - const DWARFDIE &orig_die, - const lldb::addr_t func_low_pc, - bool parse_siblings, bool parse_children, - VariableList *cc_variable_list) { - if (!orig_die) - return 0; +void SymbolFileDWARF::ParseAndAppendGlobalVariable( + const SymbolContext &sc, const DWARFDIE &die, + VariableList &cc_variable_list) { + if (!die) + return; - VariableListSP variable_list_sp; + dw_tag_t tag = die.Tag(); + if (tag != DW_TAG_variable && tag != DW_TAG_constant) + return; - size_t vars_added = 0; - DWARFDIE die = orig_die; - while (die) { - dw_tag_t tag = die.Tag(); + // Check to see if we have already parsed this variable or constant? + VariableSP var_sp = GetDIEToVariable()[die.GetDIE()]; + if (var_sp) { + cc_variable_list.AddVariableIfUnique(var_sp); + return; + } - // Check to see if we have already parsed this variable or constant? - VariableSP var_sp = GetDIEToVariable()[die.GetDIE()]; - if (var_sp) { - if (cc_variable_list) - cc_variable_list->AddVariableIfUnique(var_sp); + // We haven't parsed the variable yet, lets do that now. Also, let us include + // the variable in the relevant compilation unit's variable list, if it + // exists. + VariableListSP variable_list_sp; + DWARFDIE sc_parent_die = GetParentSymbolContextDIE(die); + dw_tag_t parent_tag = sc_parent_die.Tag(); + switch (parent_tag) { + case DW_TAG_compile_unit: + case DW_TAG_partial_unit: + if (sc.comp_unit != nullptr) { + variable_list_sp = sc.comp_unit->GetVariableList(false); } else { - // We haven't already parsed it, lets do that now. - if ((tag == DW_TAG_variable) || (tag == DW_TAG_constant) || - (tag == DW_TAG_formal_parameter && sc.function)) { - if (variable_list_sp.get() == nullptr) { - DWARFDIE sc_parent_die = GetParentSymbolContextDIE(orig_die); - dw_tag_t parent_tag = sc_parent_die.Tag(); - switch (parent_tag) { - case DW_TAG_compile_unit: - case DW_TAG_partial_unit: - if (sc.comp_unit != nullptr) { - variable_list_sp = sc.comp_unit->GetVariableList(false); - if (variable_list_sp.get() == nullptr) { - variable_list_sp = std::make_shared<VariableList>(); - } - } else { - GetObjectFile()->GetModule()->ReportError( - "parent 0x%8.8" PRIx64 " %s with no valid compile unit in " - "symbol context for 0x%8.8" PRIx64 " %s.\n", - sc_parent_die.GetID(), sc_parent_die.GetTagAsCString(), - orig_die.GetID(), orig_die.GetTagAsCString()); - } - break; + GetObjectFile()->GetModule()->ReportError( + "parent 0x%8.8" PRIx64 " %s with no valid compile unit in " + "symbol context for 0x%8.8" PRIx64 " %s.\n", + sc_parent_die.GetID(), sc_parent_die.GetTagAsCString(), die.GetID(), + die.GetTagAsCString()); + return; + } + break; - case DW_TAG_subprogram: - case DW_TAG_inlined_subroutine: - case DW_TAG_lexical_block: - if (sc.function != nullptr) { - // Check to see if we already have parsed the variables for the - // given scope - - Block *block = sc.function->GetBlock(true).FindBlockByID( - sc_parent_die.GetID()); - if (block == nullptr) { - // This must be a specification or abstract origin with a - // concrete block counterpart in the current function. We need - // to find the concrete block so we can correctly add the - // variable to it - const DWARFDIE concrete_block_die = - FindBlockContainingSpecification( - GetDIE(sc.function->GetID()), - sc_parent_die.GetOffset()); - if (concrete_block_die) - block = sc.function->GetBlock(true).FindBlockByID( - concrete_block_die.GetID()); - } + default: + GetObjectFile()->GetModule()->ReportError( + "didn't find appropriate parent DIE for variable list for " + "0x%8.8" PRIx64 " %s.\n", + die.GetID(), die.GetTagAsCString()); + return; + } - if (block != nullptr) { - const bool can_create = false; - variable_list_sp = block->GetBlockVariableList(can_create); - if (variable_list_sp.get() == nullptr) { - variable_list_sp = std::make_shared<VariableList>(); - block->SetVariableList(variable_list_sp); - } - } - } - break; + var_sp = ParseVariableDIECached(sc, die); + if (!var_sp) + return; - default: - GetObjectFile()->GetModule()->ReportError( - "didn't find appropriate parent DIE for variable list for " - "0x%8.8" PRIx64 " %s.\n", - orig_die.GetID(), orig_die.GetTagAsCString()); - break; - } - } + cc_variable_list.AddVariableIfUnique(var_sp); + if (variable_list_sp) + variable_list_sp->AddVariableIfUnique(var_sp); +} + +DIEArray +SymbolFileDWARF::MergeBlockAbstractParameters(const DWARFDIE &block_die, + DIEArray &&variable_dies) { + // DW_TAG_inline_subroutine objects may omit DW_TAG_formal_parameter in + // instances of the function when they are unused (i.e., the parameter's + // location list would be empty). The current DW_TAG_inline_subroutine may + // refer to another DW_TAG_subprogram that might actually have the definitions + // of the parameters and we need to include these so they show up in the + // variables for this function (for example, in a stack trace). Let us try to + // find the abstract subprogram that might contain the parameter definitions + // and merge with the concrete parameters. + + // Nothing to merge if the block is not an inlined function. + if (block_die.Tag() != DW_TAG_inlined_subroutine) { + return std::move(variable_dies); + } + + // Nothing to merge if the block does not have abstract parameters. + DWARFDIE abs_die = block_die.GetReferencedDIE(DW_AT_abstract_origin); + if (!abs_die || abs_die.Tag() != DW_TAG_subprogram || + !abs_die.HasChildren()) { + return std::move(variable_dies); + } + + // For each abstract parameter, if we have its concrete counterpart, insert + // it. Otherwise, insert the abstract parameter. + DIEArray::iterator concrete_it = variable_dies.begin(); + DWARFDIE abstract_child = abs_die.GetFirstChild(); + DIEArray merged; + bool did_merge_abstract = false; + for (; abstract_child; abstract_child = abstract_child.GetSibling()) { + if (abstract_child.Tag() == DW_TAG_formal_parameter) { + if (concrete_it == variable_dies.end() || + GetDIE(*concrete_it).Tag() != DW_TAG_formal_parameter) { + // We arrived at the end of the concrete parameter list, so all + // the remaining abstract parameters must have been omitted. + // Let us insert them to the merged list here. + merged.push_back(*abstract_child.GetDIERef()); + did_merge_abstract = true; + continue; + } - if (variable_list_sp) { - VariableSP var_sp(ParseVariableDIE(sc, die, func_low_pc)); - if (var_sp) { - variable_list_sp->AddVariableIfUnique(var_sp); - if (cc_variable_list) - cc_variable_list->AddVariableIfUnique(var_sp); - ++vars_added; - } - } + DWARFDIE origin_of_concrete = + GetDIE(*concrete_it).GetReferencedDIE(DW_AT_abstract_origin); + if (origin_of_concrete == abstract_child) { + // The current abstract parameter is the origin of the current + // concrete parameter, just push the concrete parameter. + merged.push_back(*concrete_it); + ++concrete_it; + } else { + // Otherwise, the parameter must have been omitted from the concrete + // function, so insert the abstract one. + merged.push_back(*abstract_child.GetDIERef()); + did_merge_abstract = true; } } + } - bool skip_children = (sc.function == nullptr && tag == DW_TAG_subprogram); + // Shortcut if no merging happened. + if (!did_merge_abstract) + return std::move(variable_dies); - if (!skip_children && parse_children && die.HasChildren()) { - vars_added += ParseVariables(sc, die.GetFirstChild(), func_low_pc, true, - true, cc_variable_list); + // We inserted all the abstract parameters (or their concrete counterparts). + // Let us insert all the remaining concrete variables to the merged list. + // During the insertion, let us check there are no remaining concrete + // formal parameters. If that's the case, then just bailout from the merge - + // the variable list is malformed. + for (; concrete_it != variable_dies.end(); ++concrete_it) { + if (GetDIE(*concrete_it).Tag() == DW_TAG_formal_parameter) { + return std::move(variable_dies); } + merged.push_back(*concrete_it); + } + return merged; +} - if (parse_siblings) - die = die.GetSibling(); - else - die.Clear(); +size_t SymbolFileDWARF::ParseVariablesInFunctionContext( + const SymbolContext &sc, const DWARFDIE &die, + const lldb::addr_t func_low_pc) { + if (!die || !sc.function) + return 0; + + DIEArray dummy_block_variables; // The recursive call should not add anything + // to this vector because |die| should be a + // subprogram, so all variables will be added + // to the subprogram's list. + return ParseVariablesInFunctionContextRecursive(sc, die, func_low_pc, + dummy_block_variables); +} + +// This method parses all the variables in the blocks in the subtree of |die|, +// and inserts them to the variable list for all the nested blocks. +// The uninserted variables for the current block are accumulated in +// |accumulator|. +size_t SymbolFileDWARF::ParseVariablesInFunctionContextRecursive( + const lldb_private::SymbolContext &sc, const DWARFDIE &die, + lldb::addr_t func_low_pc, DIEArray &accumulator) { + size_t vars_added = 0; + dw_tag_t tag = die.Tag(); + + if ((tag == DW_TAG_variable) || (tag == DW_TAG_constant) || + (tag == DW_TAG_formal_parameter)) { + accumulator.push_back(*die.GetDIERef()); + } + + switch (tag) { + case DW_TAG_subprogram: + case DW_TAG_inlined_subroutine: + case DW_TAG_lexical_block: { + // If we start a new block, compute a new block variable list and recurse. + Block *block = + sc.function->GetBlock(/*can_create=*/true).FindBlockByID(die.GetID()); + if (block == nullptr) { + // This must be a specification or abstract origin with a + // concrete block counterpart in the current function. We need + // to find the concrete block so we can correctly add the + // variable to it. + const DWARFDIE concrete_block_die = FindBlockContainingSpecification( + GetDIE(sc.function->GetID()), die.GetOffset()); + if (concrete_block_die) + block = sc.function->GetBlock(/*can_create=*/true) + .FindBlockByID(concrete_block_die.GetID()); + } + + if (block == nullptr) + return 0; + + const bool can_create = false; + VariableListSP block_variable_list_sp = + block->GetBlockVariableList(can_create); + if (block_variable_list_sp.get() == nullptr) { + block_variable_list_sp = std::make_shared<VariableList>(); + block->SetVariableList(block_variable_list_sp); + } + + DIEArray block_variables; + for (DWARFDIE child = die.GetFirstChild(); child; + child = child.GetSibling()) { + vars_added += ParseVariablesInFunctionContextRecursive( + sc, child, func_low_pc, block_variables); + } + block_variables = + MergeBlockAbstractParameters(die, std::move(block_variables)); + vars_added += PopulateBlockVariableList(*block_variable_list_sp, sc, + block_variables, func_low_pc); + break; + } + + default: + // Recurse to children with the same variable accumulator. + for (DWARFDIE child = die.GetFirstChild(); child; + child = child.GetSibling()) { + vars_added += ParseVariablesInFunctionContextRecursive( + sc, child, func_low_pc, accumulator); + } + break; } + return vars_added; } +size_t SymbolFileDWARF::PopulateBlockVariableList( + VariableList &variable_list, const lldb_private::SymbolContext &sc, + llvm::ArrayRef<DIERef> variable_dies, lldb::addr_t func_low_pc) { + // Parse the variable DIEs and insert them to the list. + for (auto &die : variable_dies) { + if (VariableSP var_sp = ParseVariableDIE(sc, GetDIE(die), func_low_pc)) { + variable_list.AddVariableIfUnique(var_sp); + } + } + return variable_dies.size(); +} + /// Collect call site parameters in a DW_TAG_call_site DIE. static CallSiteParameterArray CollectCallSiteParameters(ModuleSP module, DWARFDIE call_site_die) { @@ -3766,11 +3959,6 @@ SymbolFileDWARF::ParseCallEdgesInFunction(UserID func_id) { return {}; } -// PluginInterface protocol -ConstString SymbolFileDWARF::GetPluginName() { return GetPluginNameStatic(); } - -uint32_t SymbolFileDWARF::GetPluginVersion() { return 1; } - void SymbolFileDWARF::Dump(lldb_private::Stream &s) { SymbolFile::Dump(s); m_index->Dump(s); @@ -3784,7 +3972,7 @@ void SymbolFileDWARF::DumpClangAST(Stream &s) { llvm::dyn_cast_or_null<TypeSystemClang>(&ts_or_err.get()); if (!clang) return; - clang->Dump(s); + clang->Dump(s.AsRawOstream()); } SymbolFileDWARFDebugMap *SymbolFileDWARF::GetDebugMapSymfile() { @@ -3889,3 +4077,9 @@ LanguageType SymbolFileDWARF::GetLanguageFamily(DWARFUnit &unit) { lang = DW_LANG_C_plus_plus; return LanguageTypeFromDWARF(lang); } + +StatsDuration SymbolFileDWARF::GetDebugInfoIndexTime() { + if (m_index) + return m_index->GetIndexTime(); + return StatsDuration(0.0); +} diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h index d9feeef549ed..271ce7be1eea 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h @@ -24,6 +24,7 @@ #include "lldb/Symbol/DebugMacros.h" #include "lldb/Symbol/SymbolContext.h" #include "lldb/Symbol/SymbolFile.h" +#include "lldb/Target/Statistics.h" #include "lldb/Utility/ConstString.h" #include "lldb/Utility/Flags.h" #include "lldb/Utility/RangeMap.h" @@ -83,9 +84,9 @@ public: static void DebuggerInitialize(lldb_private::Debugger &debugger); - static lldb_private::ConstString GetPluginNameStatic(); + static llvm::StringRef GetPluginNameStatic() { return "dwarf"; } - static const char *GetPluginDescriptionStatic(); + static llvm::StringRef GetPluginDescriptionStatic(); static lldb_private::SymbolFile * CreateInstance(lldb::ObjectFileSP objfile_sp); @@ -218,9 +219,7 @@ public: std::recursive_mutex &GetModuleMutex() const override; // PluginInterface protocol - lldb_private::ConstString GetPluginName() override; - - uint32_t GetPluginVersion() override; + llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); } DWARFDebugAbbrev *DebugAbbrev(); @@ -320,6 +319,16 @@ public: /// Same as GetLanguage() but reports all C++ versions as C++ (no version). static lldb::LanguageType GetLanguageFamily(DWARFUnit &unit); + lldb_private::StatsDuration GetDebugInfoParseTime() override { + return m_parse_time; + } + lldb_private::StatsDuration GetDebugInfoIndexTime() override; + + lldb_private::StatsDuration &GetDebugInfoParseTimeRef() { + return m_parse_time; + } + + protected: typedef llvm::DenseMap<const DWARFDebugInfoEntry *, lldb_private::Type *> DIEToTypePtr; @@ -368,6 +377,9 @@ protected: lldb::TypeSP ParseType(const lldb_private::SymbolContext &sc, const DWARFDIE &die, bool *type_is_new); + bool ParseSupportFiles(DWARFUnit &dwarf_cu, const lldb::ModuleSP &module, + lldb_private::FileSpecList &support_files); + lldb_private::Type *ResolveTypeUID(const DWARFDIE &die, bool assert_not_being_parsed); @@ -376,12 +388,29 @@ protected: lldb::VariableSP ParseVariableDIE(const lldb_private::SymbolContext &sc, const DWARFDIE &die, const lldb::addr_t func_low_pc); + lldb::VariableSP ParseVariableDIECached(const lldb_private::SymbolContext &sc, + const DWARFDIE &die); - size_t ParseVariables(const lldb_private::SymbolContext &sc, - const DWARFDIE &orig_die, - const lldb::addr_t func_low_pc, bool parse_siblings, - bool parse_children, - lldb_private::VariableList *cc_variable_list = nullptr); + void + ParseAndAppendGlobalVariable(const lldb_private::SymbolContext &sc, + const DWARFDIE &die, + lldb_private::VariableList &cc_variable_list); + + size_t ParseVariablesInFunctionContext(const lldb_private::SymbolContext &sc, + const DWARFDIE &die, + const lldb::addr_t func_low_pc); + + size_t ParseVariablesInFunctionContextRecursive( + const lldb_private::SymbolContext &sc, const DWARFDIE &die, + lldb::addr_t func_low_pc, DIEArray &accumulator); + + size_t PopulateBlockVariableList(lldb_private::VariableList &variable_list, + const lldb_private::SymbolContext &sc, + llvm::ArrayRef<DIERef> variable_dies, + lldb::addr_t func_low_pc); + + DIEArray MergeBlockAbstractParameters(const DWARFDIE &block_die, + DIEArray &&variable_dies); bool ClassOrStructIsVirtual(const DWARFDIE &die); @@ -483,6 +512,11 @@ protected: const lldb_private::FileSpecList &GetTypeUnitSupportFiles(DWARFTypeUnit &tu); + void InitializeFirstCodeAddressRecursive( + const lldb_private::SectionList §ion_list); + + void InitializeFirstCodeAddress(); + lldb::ModuleWP m_debug_map_module_wp; SymbolFileDWARFDebugMap *m_debug_map_symfile; @@ -518,6 +552,14 @@ protected: llvm::DenseMap<dw_offset_t, lldb_private::FileSpecList> m_type_unit_support_files; std::vector<uint32_t> m_lldb_cu_to_dwarf_unit; + /// DWARF does not provide a good way for traditional (concatenating) linkers + /// to invalidate debug info describing dead-stripped code. These linkers will + /// keep the debug info but resolve any addresses referring to such code as + /// zero (BFD) or a small positive integer (zero + relocation addend -- GOLD). + /// Try to filter out this debug info by comparing it to the lowest code + /// address in the module. + lldb::addr_t m_first_code_address = LLDB_INVALID_ADDRESS; + lldb_private::StatsDuration m_parse_time{0.0}; }; #endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_SYMBOLFILEDWARF_H diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp index 4e2e5e16637b..2491f6af8c19 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp @@ -16,6 +16,7 @@ #include "lldb/Host/FileSystem.h" #include "lldb/Utility/RangeMap.h" #include "lldb/Utility/RegularExpression.h" +#include "lldb/Utility/Timer.h" //#define DEBUG_OSO_DMAP // DO NOT CHECKIN WITH THIS NOT COMMENTED OUT #if defined(DEBUG_OSO_DMAP) @@ -33,9 +34,6 @@ #include "LogChannelDWARF.h" #include "SymbolFileDWARF.h" -// Work around the fact that Timer.h pulls in the system Mach-O headers. -#include "lldb/Utility/Timer.h" - #include <memory> using namespace lldb; @@ -230,12 +228,7 @@ void SymbolFileDWARFDebugMap::Terminate() { PluginManager::UnregisterPlugin(CreateInstance); } -lldb_private::ConstString SymbolFileDWARFDebugMap::GetPluginNameStatic() { - static ConstString g_name("dwarf-debugmap"); - return g_name; -} - -const char *SymbolFileDWARFDebugMap::GetPluginDescriptionStatic() { +llvm::StringRef SymbolFileDWARFDebugMap::GetPluginDescriptionStatic() { return "DWARF and DWARF3 debug symbol file reader (debug map)."; } @@ -1236,13 +1229,6 @@ void SymbolFileDWARFDebugMap::DumpClangAST(Stream &s) { }); } -// PluginInterface protocol -lldb_private::ConstString SymbolFileDWARFDebugMap::GetPluginName() { - return GetPluginNameStatic(); -} - -uint32_t SymbolFileDWARFDebugMap::GetPluginVersion() { return 1; } - lldb::CompUnitSP SymbolFileDWARFDebugMap::GetCompileUnit(SymbolFileDWARF *oso_dwarf) { if (oso_dwarf) { @@ -1443,3 +1429,54 @@ SymbolFileDWARFDebugMap::AddOSOARanges(SymbolFileDWARF *dwarf2Data, } return num_line_entries_added; } + +uint64_t SymbolFileDWARFDebugMap::GetDebugInfoSize() { + uint64_t debug_info_size = 0; + ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool { + ObjectFile *oso_objfile = oso_dwarf->GetObjectFile(); + if (!oso_objfile) + return false; // Keep iterating + ModuleSP module_sp = oso_objfile->GetModule(); + if (!module_sp) + return false; // Keep iterating + SectionList *section_list = module_sp->GetSectionList(); + if (section_list) + debug_info_size += section_list->GetDebugInfoSize(); + return false; // Keep iterating + }); + return debug_info_size; +} + +StatsDuration SymbolFileDWARFDebugMap::GetDebugInfoParseTime() { + StatsDuration elapsed(0.0); + ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool { + ObjectFile *oso_objfile = oso_dwarf->GetObjectFile(); + if (oso_objfile) { + ModuleSP module_sp = oso_objfile->GetModule(); + if (module_sp) { + SymbolFile *symfile = module_sp->GetSymbolFile(); + if (symfile) + elapsed += symfile->GetDebugInfoParseTime(); + } + } + return false; // Keep iterating + }); + return elapsed; +} + +StatsDuration SymbolFileDWARFDebugMap::GetDebugInfoIndexTime() { + StatsDuration elapsed(0.0); + ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool { + ObjectFile *oso_objfile = oso_dwarf->GetObjectFile(); + if (oso_objfile) { + ModuleSP module_sp = oso_objfile->GetModule(); + if (module_sp) { + SymbolFile *symfile = module_sp->GetSymbolFile(); + if (symfile) + elapsed += symfile->GetDebugInfoIndexTime(); + } + } + return false; // Keep iterating + }); + return elapsed; +} diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h index 8b6624e70869..74f32442de2f 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h @@ -40,9 +40,9 @@ public: static void Terminate(); - static lldb_private::ConstString GetPluginNameStatic(); + static llvm::StringRef GetPluginNameStatic() { return "dwarf-debugmap"; } - static const char *GetPluginDescriptionStatic(); + static llvm::StringRef GetPluginDescriptionStatic(); static lldb_private::SymbolFile * CreateInstance(lldb::ObjectFileSP objfile_sp); @@ -140,9 +140,11 @@ public: void DumpClangAST(lldb_private::Stream &s) override; // PluginInterface protocol - lldb_private::ConstString GetPluginName() override; + llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); } - uint32_t GetPluginVersion() override; + uint64_t GetDebugInfoSize() override; + lldb_private::StatsDuration GetDebugInfoParseTime() override; + lldb_private::StatsDuration GetDebugInfoIndexTime() override; protected: enum { kHaveInitializedOSOs = (1 << 0), kNumFlags }; diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp index 43cf262016c2..c29fc2230a67 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp @@ -1105,7 +1105,7 @@ clang::QualType PdbAstBuilder::CreateEnumType(PdbTypeSymId id, Declaration declaration; CompilerType enum_ct = m_clang.CreateEnumerationType( - uname.c_str(), decl_context, OptionalClangModuleID(), declaration, + uname, decl_context, OptionalClangModuleID(), declaration, ToCompilerType(underlying_type), er.isScoped()); TypeSystemClang::StartTagDeclarationDefinition(enum_ct); @@ -1358,4 +1358,6 @@ PdbAstBuilder::FromCompilerDeclContext(CompilerDeclContext context) { return static_cast<clang::DeclContext *>(context.GetOpaqueDeclContext()); } -void PdbAstBuilder::Dump(Stream &stream) { m_clang.Dump(stream); } +void PdbAstBuilder::Dump(Stream &stream) { + m_clang.Dump(stream.AsRawOstream()); +} diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp index b9b075d83b6a..8af90cb66e87 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp @@ -240,12 +240,7 @@ void SymbolFileNativePDB::Terminate() { void SymbolFileNativePDB::DebuggerInitialize(Debugger &debugger) {} -ConstString SymbolFileNativePDB::GetPluginNameStatic() { - static ConstString g_name("native-pdb"); - return g_name; -} - -const char *SymbolFileNativePDB::GetPluginDescriptionStatic() { +llvm::StringRef SymbolFileNativePDB::GetPluginDescriptionStatic() { return "Microsoft PDB debug symbol cross-platform file reader."; } @@ -950,11 +945,11 @@ uint32_t SymbolFileNativePDB::ResolveSymbolContext( llvm::Optional<uint16_t> modi = m_index->GetModuleIndexForVa(file_addr); if (!modi) return 0; - CompilandIndexItem *cci = m_index->compilands().GetCompiland(*modi); - if (!cci) + CompUnitSP cu_sp = GetCompileUnitAtIndex(modi.getValue()); + if (!cu_sp) return 0; - sc.comp_unit = GetOrCreateCompileUnit(*cci).get(); + sc.comp_unit = cu_sp.get(); resolved_flags |= eSymbolContextCompUnit; } @@ -1567,9 +1562,8 @@ SymbolFileNativePDB::GetTypeSystemForLanguage(lldb::LanguageType language) { return type_system_or_err; } -ConstString SymbolFileNativePDB::GetPluginName() { - static ConstString g_name("pdb"); - return g_name; +uint64_t SymbolFileNativePDB::GetDebugInfoSize() { + // PDB files are a separate file that contains all debug info. + return m_index->pdb().getFileSize(); } -uint32_t SymbolFileNativePDB::GetPluginVersion() { return 1; } diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h index def0995065ca..56a5ec0a464d 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h @@ -60,9 +60,9 @@ public: static void DebuggerInitialize(Debugger &debugger); - static ConstString GetPluginNameStatic(); + static llvm::StringRef GetPluginNameStatic() { return "native-pdb"; } - static const char *GetPluginDescriptionStatic(); + static llvm::StringRef GetPluginDescriptionStatic(); static SymbolFile *CreateInstance(lldb::ObjectFileSP objfile_sp); @@ -75,6 +75,8 @@ public: void InitializeObject() override; + uint64_t GetDebugInfoSize() override; + // Compile Unit function calls void @@ -151,9 +153,7 @@ public: FindNamespace(ConstString name, const CompilerDeclContext &parent_decl_ctx) override; - ConstString GetPluginName() override; - - uint32_t GetPluginVersion() override; + llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); } llvm::pdb::PDBFile &GetPDBFile() { return m_index->pdb(); } const llvm::pdb::PDBFile &GetPDBFile() const { return m_index->pdb(); } diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp index 78a0d09a681a..f45287fd0fff 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp @@ -497,7 +497,7 @@ lldb::TypeSP PDBASTParser::CreateLLDBTypeFromPDBType(const PDBSymbol &type) { // Class). Set it false for now. bool isScoped = false; - ast_enum = m_ast.CreateEnumerationType(name.c_str(), decl_context, + ast_enum = m_ast.CreateEnumerationType(name, decl_context, OptionalClangModuleID(), decl, builtin_type, isScoped); diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp index 6b30ad26dca7..45dfc4b9a152 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp @@ -52,6 +52,10 @@ #include "Plugins/Language/CPlusPlus/MSVCUndecoratedNameParser.h" #include "Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h" +#if defined(_WIN32) +#include "llvm/Config/config.h" +#endif + using namespace lldb; using namespace lldb_private; using namespace llvm::pdb; @@ -83,14 +87,16 @@ bool ShouldAddLine(uint32_t requested_line, uint32_t actual_line, static bool ShouldUseNativeReader() { #if defined(_WIN32) +#if LLVM_ENABLE_DIA_SDK llvm::StringRef use_native = ::getenv("LLDB_USE_NATIVE_PDB_READER"); - return use_native.equals_insensitive("on") || - use_native.equals_insensitive("yes") || - use_native.equals_insensitive("1") || - use_native.equals_insensitive("true"); -#else - return true; + if (!use_native.equals_insensitive("on") && + !use_native.equals_insensitive("yes") && + !use_native.equals_insensitive("1") && + !use_native.equals_insensitive("true")) + return false; +#endif #endif + return true; } void SymbolFilePDB::Initialize() { @@ -113,12 +119,7 @@ void SymbolFilePDB::Terminate() { void SymbolFilePDB::DebuggerInitialize(lldb_private::Debugger &debugger) {} -lldb_private::ConstString SymbolFilePDB::GetPluginNameStatic() { - static ConstString g_name("pdb"); - return g_name; -} - -const char *SymbolFilePDB::GetPluginDescriptionStatic() { +llvm::StringRef SymbolFilePDB::GetPluginDescriptionStatic() { return "Microsoft PDB debug symbol file reader."; } @@ -1455,7 +1456,7 @@ void SymbolFilePDB::DumpClangAST(Stream &s) { llvm::dyn_cast_or_null<TypeSystemClang>(&type_system_or_err.get()); if (!clang_type_system) return; - clang_type_system->Dump(s); + clang_type_system->Dump(s.AsRawOstream()); } void SymbolFilePDB::FindTypesByRegex( @@ -1707,13 +1708,6 @@ SymbolFilePDB::FindNamespace(lldb_private::ConstString name, return clang_type_system->CreateDeclContext(namespace_decl); } -lldb_private::ConstString SymbolFilePDB::GetPluginName() { - static ConstString g_name("pdb"); - return g_name; -} - -uint32_t SymbolFilePDB::GetPluginVersion() { return 1; } - IPDBSession &SymbolFilePDB::GetPDBSession() { return *m_session_up; } const IPDBSession &SymbolFilePDB::GetPDBSession() const { diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.h b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.h index 2171b7f686cc..69f1d268edfd 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.h +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.h @@ -41,9 +41,9 @@ public: static void DebuggerInitialize(lldb_private::Debugger &debugger); - static lldb_private::ConstString GetPluginNameStatic(); + static llvm::StringRef GetPluginNameStatic() { return "pdb"; } - static const char *GetPluginDescriptionStatic(); + static llvm::StringRef GetPluginDescriptionStatic(); static lldb_private::SymbolFile * CreateInstance(lldb::ObjectFileSP objfile_sp); @@ -161,9 +161,7 @@ public: lldb_private::ConstString name, const lldb_private::CompilerDeclContext &parent_decl_ctx) override; - lldb_private::ConstString GetPluginName() override; - - uint32_t GetPluginVersion() override; + llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); } llvm::pdb::IPDBSession &GetPDBSession(); diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp index 3a5e02d4fb86..d95cfea5e872 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp @@ -38,12 +38,7 @@ void SymbolFileSymtab::Terminate() { PluginManager::UnregisterPlugin(CreateInstance); } -lldb_private::ConstString SymbolFileSymtab::GetPluginNameStatic() { - static ConstString g_name("symtab"); - return g_name; -} - -const char *SymbolFileSymtab::GetPluginDescriptionStatic() { +llvm::StringRef SymbolFileSymtab::GetPluginDescriptionStatic() { return "Reads debug symbols from an object file's symbol table."; } @@ -260,10 +255,3 @@ uint32_t SymbolFileSymtab::ResolveSymbolContext(const Address &so_addr, } return resolved_flags; } - -// PluginInterface protocol -lldb_private::ConstString SymbolFileSymtab::GetPluginName() { - return GetPluginNameStatic(); -} - -uint32_t SymbolFileSymtab::GetPluginVersion() { return 1; } diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.h b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.h index 377c41e50770..2dad12baac6f 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.h +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.h @@ -36,9 +36,9 @@ public: static void Terminate(); - static lldb_private::ConstString GetPluginNameStatic(); + static llvm::StringRef GetPluginNameStatic() { return "symtab"; } - static const char *GetPluginDescriptionStatic(); + static llvm::StringRef GetPluginDescriptionStatic(); static lldb_private::SymbolFile * CreateInstance(lldb::ObjectFileSP objfile_sp); @@ -85,9 +85,7 @@ public: lldb_private::TypeList &type_list) override; // PluginInterface protocol - lldb_private::ConstString GetPluginName() override; - - uint32_t GetPluginVersion() override; + llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); } protected: uint32_t CalculateNumCompileUnits() override; diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolVendor/ELF/SymbolVendorELF.cpp b/contrib/llvm-project/lldb/source/Plugins/SymbolVendor/ELF/SymbolVendorELF.cpp index 9130eed63e43..0a98f5032b77 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolVendor/ELF/SymbolVendorELF.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolVendor/ELF/SymbolVendorELF.cpp @@ -40,12 +40,7 @@ void SymbolVendorELF::Terminate() { PluginManager::UnregisterPlugin(CreateInstance); } -lldb_private::ConstString SymbolVendorELF::GetPluginNameStatic() { - static ConstString g_name("ELF"); - return g_name; -} - -const char *SymbolVendorELF::GetPluginDescriptionStatic() { +llvm::StringRef SymbolVendorELF::GetPluginDescriptionStatic() { return "Symbol vendor for ELF that looks for dSYM files that match " "executables."; } @@ -144,8 +139,3 @@ SymbolVendorELF::CreateInstance(const lldb::ModuleSP &module_sp, symbol_vendor->AddSymbolFileRepresentation(dsym_objfile_sp); return symbol_vendor; } - -// PluginInterface protocol -ConstString SymbolVendorELF::GetPluginName() { return GetPluginNameStatic(); } - -uint32_t SymbolVendorELF::GetPluginVersion() { return 1; } diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolVendor/ELF/SymbolVendorELF.h b/contrib/llvm-project/lldb/source/Plugins/SymbolVendor/ELF/SymbolVendorELF.h index 2080084a15b8..13a1071e38ab 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolVendor/ELF/SymbolVendorELF.h +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolVendor/ELF/SymbolVendorELF.h @@ -22,18 +22,16 @@ public: static void Terminate(); - static lldb_private::ConstString GetPluginNameStatic(); + static llvm::StringRef GetPluginNameStatic() { return "ELF"; } - static const char *GetPluginDescriptionStatic(); + static llvm::StringRef GetPluginDescriptionStatic(); static lldb_private::SymbolVendor * CreateInstance(const lldb::ModuleSP &module_sp, lldb_private::Stream *feedback_strm); // PluginInterface protocol - lldb_private::ConstString GetPluginName() override; - - uint32_t GetPluginVersion() override; + llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); } }; #endif // LLDB_SOURCE_PLUGINS_SYMBOLVENDOR_ELF_SYMBOLVENDORELF_H diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolVendor/wasm/SymbolVendorWasm.cpp b/contrib/llvm-project/lldb/source/Plugins/SymbolVendor/wasm/SymbolVendorWasm.cpp index 2b2840796579..9da5b0133d37 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolVendor/wasm/SymbolVendorWasm.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolVendor/wasm/SymbolVendorWasm.cpp @@ -41,12 +41,7 @@ void SymbolVendorWasm::Terminate() { PluginManager::UnregisterPlugin(CreateInstance); } -lldb_private::ConstString SymbolVendorWasm::GetPluginNameStatic() { - static ConstString g_name("WASM"); - return g_name; -} - -const char *SymbolVendorWasm::GetPluginDescriptionStatic() { +llvm::StringRef SymbolVendorWasm::GetPluginDescriptionStatic() { return "Symbol vendor for WASM that looks for dwo files that match " "executables."; } @@ -139,8 +134,3 @@ SymbolVendorWasm::CreateInstance(const lldb::ModuleSP &module_sp, symbol_vendor->AddSymbolFileRepresentation(sym_objfile_sp); return symbol_vendor; } - -// PluginInterface protocol -ConstString SymbolVendorWasm::GetPluginName() { return GetPluginNameStatic(); } - -uint32_t SymbolVendorWasm::GetPluginVersion() { return 1; } diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolVendor/wasm/SymbolVendorWasm.h b/contrib/llvm-project/lldb/source/Plugins/SymbolVendor/wasm/SymbolVendorWasm.h index b212337e0549..af692c6e9e00 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolVendor/wasm/SymbolVendorWasm.h +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolVendor/wasm/SymbolVendorWasm.h @@ -21,8 +21,8 @@ public: static void Initialize(); static void Terminate(); - static lldb_private::ConstString GetPluginNameStatic(); - static const char *GetPluginDescriptionStatic(); + static llvm::StringRef GetPluginNameStatic() { return "WASM"; } + static llvm::StringRef GetPluginDescriptionStatic(); static lldb_private::SymbolVendor * CreateInstance(const lldb::ModuleSP &module_sp, @@ -30,8 +30,7 @@ public: /// PluginInterface protocol. /// \{ - lldb_private::ConstString GetPluginName() override; - uint32_t GetPluginVersion() override; + llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); } /// \} }; diff --git a/contrib/llvm-project/lldb/source/Plugins/Trace/common/TraceJSONStructs.cpp b/contrib/llvm-project/lldb/source/Plugins/Trace/common/TraceJSONStructs.cpp new file mode 100644 index 000000000000..1773a6003701 --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Trace/common/TraceJSONStructs.cpp @@ -0,0 +1,106 @@ +//===-- TraceSessionFileStructs.cpp ---------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===/ + +#include "TraceJSONStructs.h" +#include "ThreadPostMortemTrace.h" +#include "lldb/Core/Debugger.h" +#include "lldb/Core/Module.h" +#include "lldb/Target/Process.h" +#include "lldb/Target/Target.h" +#include <sstream> + +using namespace lldb_private; +namespace llvm { +namespace json { + +llvm::json::Value toJSON(const JSONModule &module) { + llvm::json::Object json_module; + json_module["systemPath"] = module.system_path; + if (module.file) + json_module["file"] = *module.file; + std::ostringstream oss; + oss << "0x" << std::hex << module.load_address.value; + json_module["loadAddress"] = oss.str(); + if (module.uuid) + json_module["uuid"] = *module.uuid; + return std::move(json_module); +} + +llvm::json::Value toJSON(const JSONThread &thread) { + return Value(Object{{"tid", thread.tid}, {"traceFile", thread.trace_file}}); +} + +llvm::json::Value toJSON(const JSONProcess &process) { + llvm::json::Object json_process; + json_process["pid"] = process.pid; + json_process["triple"] = process.triple; + + llvm::json::Array threads_arr; + for (JSONThread e : process.threads) + threads_arr.push_back(toJSON(e)); + + json_process["threads"] = llvm::json::Value(std::move(threads_arr)); + + llvm::json::Array modules_arr; + for (JSONModule e : process.modules) + modules_arr.push_back(toJSON(e)); + + json_process["modules"] = llvm::json::Value(std::move(modules_arr)); + + return std::move(json_process); +} + +llvm::json::Value toJSON(const JSONTraceSessionBase &session) { + llvm::json::Array arr; + for (JSONProcess e : session.processes) + arr.push_back(toJSON(e)); + + return std::move(arr); +} + +bool fromJSON(const Value &value, JSONAddress &address, Path path) { + Optional<StringRef> s = value.getAsString(); + if (s.hasValue() && !s->getAsInteger(0, address.value)) + return true; + + path.report("expected numeric string"); + return false; +} + +bool fromJSON(const Value &value, JSONModule &module, Path path) { + ObjectMapper o(value, path); + return o && o.map("systemPath", module.system_path) && + o.map("file", module.file) && + o.map("loadAddress", module.load_address) && + o.map("uuid", module.uuid); +} + +bool fromJSON(const Value &value, JSONThread &thread, Path path) { + ObjectMapper o(value, path); + return o && o.map("tid", thread.tid) && o.map("traceFile", thread.trace_file); +} + +bool fromJSON(const Value &value, JSONProcess &process, Path path) { + ObjectMapper o(value, path); + return o && o.map("pid", process.pid) && o.map("triple", process.triple) && + o.map("threads", process.threads) && o.map("modules", process.modules); +} + +bool fromJSON(const Value &value, JSONTracePluginSettings &plugin_settings, + Path path) { + ObjectMapper o(value, path); + return o && o.map("type", plugin_settings.type); +} + +bool fromJSON(const Value &value, JSONTraceSessionBase &session, Path path) { + ObjectMapper o(value, path); + return o && o.map("processes", session.processes); +} + +} // namespace json +} // namespace llvm diff --git a/contrib/llvm-project/lldb/source/Plugins/Trace/common/TraceJSONStructs.h b/contrib/llvm-project/lldb/source/Plugins/Trace/common/TraceJSONStructs.h new file mode 100644 index 000000000000..e01c33bf0d6a --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Trace/common/TraceJSONStructs.h @@ -0,0 +1,98 @@ +//===-- TraceJSONStruct.h ---------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_TARGET_TRACEJSONSTRUCTS_H +#define LLDB_TARGET_TRACEJSONSTRUCTS_H + +#include "lldb/lldb-types.h" +#include "llvm/Support/JSON.h" + +namespace lldb_private { + +struct JSONAddress { + lldb::addr_t value; +}; + +struct JSONModule { + std::string system_path; + llvm::Optional<std::string> file; + JSONAddress load_address; + llvm::Optional<std::string> uuid; +}; + +struct JSONThread { + int64_t tid; + std::string trace_file; +}; + +struct JSONProcess { + int64_t pid; + std::string triple; + std::vector<JSONThread> threads; + std::vector<JSONModule> modules; +}; + +struct JSONTracePluginSettings { + std::string type; +}; + +struct JSONTraceSessionBase { + std::vector<JSONProcess> processes; +}; + +/// The trace plug-in implementation should provide its own TPluginSettings, +/// which corresponds to the "trace" section of the schema. +template <class TPluginSettings> +struct JSONTraceSession : JSONTraceSessionBase { + TPluginSettings trace; +}; + +} // namespace lldb_private + +namespace llvm { +namespace json { + +llvm::json::Value toJSON(const lldb_private::JSONModule &module); + +llvm::json::Value toJSON(const lldb_private::JSONThread &thread); + +llvm::json::Value toJSON(const lldb_private::JSONProcess &process); + +llvm::json::Value +toJSON(const lldb_private::JSONTraceSessionBase &session_base); + +bool fromJSON(const Value &value, lldb_private::JSONAddress &address, + Path path); + +bool fromJSON(const Value &value, lldb_private::JSONModule &module, Path path); + +bool fromJSON(const Value &value, lldb_private::JSONThread &thread, Path path); + +bool fromJSON(const Value &value, lldb_private::JSONProcess &process, + Path path); + +bool fromJSON(const Value &value, + lldb_private::JSONTracePluginSettings &plugin_settings, + Path path); + +bool fromJSON(const Value &value, lldb_private::JSONTraceSessionBase &session, + Path path); + +template <class TPluginSettings> +bool fromJSON(const Value &value, + lldb_private::JSONTraceSession<TPluginSettings> &session, + Path path) { + ObjectMapper o(value, path); + return o && o.map("trace", session.trace) && + fromJSON(value, (lldb_private::JSONTraceSessionBase &)session, path); +} + +} // namespace json +} // namespace llvm + +#endif // LLDB_TARGET_TRACEJSONSTRUCTS_H diff --git a/contrib/llvm-project/lldb/source/Plugins/Trace/common/TraceSessionFileParser.cpp b/contrib/llvm-project/lldb/source/Plugins/Trace/common/TraceSessionFileParser.cpp index c88ad9dc6a59..b26704ca34be 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Trace/common/TraceSessionFileParser.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Trace/common/TraceSessionFileParser.cpp @@ -170,55 +170,3 @@ TraceSessionFileParser::ParseCommonSessionFile( } return parsed_processes; } - -namespace llvm { -namespace json { - -bool fromJSON(const Value &value, TraceSessionFileParser::JSONAddress &address, - Path path) { - Optional<StringRef> s = value.getAsString(); - if (s.hasValue() && !s->getAsInteger(0, address.value)) - return true; - - path.report("expected numeric string"); - return false; -} - -bool fromJSON(const Value &value, TraceSessionFileParser::JSONModule &module, - Path path) { - ObjectMapper o(value, path); - return o && o.map("systemPath", module.system_path) && - o.map("file", module.file) && - o.map("loadAddress", module.load_address) && - o.map("uuid", module.uuid); -} - -bool fromJSON(const Value &value, TraceSessionFileParser::JSONThread &thread, - Path path) { - ObjectMapper o(value, path); - return o && o.map("tid", thread.tid) && o.map("traceFile", thread.trace_file); -} - -bool fromJSON(const Value &value, TraceSessionFileParser::JSONProcess &process, - Path path) { - ObjectMapper o(value, path); - return o && o.map("pid", process.pid) && o.map("triple", process.triple) && - o.map("threads", process.threads) && o.map("modules", process.modules); -} - -bool fromJSON(const Value &value, - TraceSessionFileParser::JSONTracePluginSettings &plugin_settings, - Path path) { - ObjectMapper o(value, path); - return o && o.map("type", plugin_settings.type); -} - -bool fromJSON(const Value &value, - TraceSessionFileParser::JSONTraceSessionBase &session, - Path path) { - ObjectMapper o(value, path); - return o && o.map("processes", session.processes); -} - -} // namespace json -} // namespace llvm diff --git a/contrib/llvm-project/lldb/source/Plugins/Trace/common/TraceSessionFileParser.h b/contrib/llvm-project/lldb/source/Plugins/Trace/common/TraceSessionFileParser.h index 6abaffcecd3a..19cc2f59ded7 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Trace/common/TraceSessionFileParser.h +++ b/contrib/llvm-project/lldb/source/Plugins/Trace/common/TraceSessionFileParser.h @@ -9,9 +9,8 @@ #ifndef LLDB_TARGET_TRACESESSIONPARSER_H #define LLDB_TARGET_TRACESESSIONPARSER_H -#include "llvm/Support/JSON.h" - #include "ThreadPostMortemTrace.h" +#include "TraceJSONStructs.h" namespace lldb_private { @@ -24,46 +23,6 @@ namespace lldb_private { /// See \a Trace::FindPlugin for more information regarding these JSON files. class TraceSessionFileParser { public: - /// C++ structs representing the JSON trace session. - /// \{ - struct JSONAddress { - lldb::addr_t value; - }; - - struct JSONModule { - std::string system_path; - llvm::Optional<std::string> file; - JSONAddress load_address; - llvm::Optional<std::string> uuid; - }; - - struct JSONThread { - int64_t tid; - std::string trace_file; - }; - - struct JSONProcess { - int64_t pid; - std::string triple; - std::vector<JSONThread> threads; - std::vector<JSONModule> modules; - }; - - struct JSONTracePluginSettings { - std::string type; - }; - - struct JSONTraceSessionBase { - std::vector<JSONProcess> processes; - }; - - /// The trace plug-in implementation should provide its own TPluginSettings, - /// which corresponds to the "trace" section of the schema. - template <class TPluginSettings> - struct JSONTraceSession : JSONTraceSessionBase { - TPluginSettings trace; - }; - /// \} /// Helper struct holding the objects created when parsing a process struct ParsedProcess { @@ -130,50 +89,5 @@ protected: }; } // namespace lldb_private -namespace llvm { -namespace json { - -bool fromJSON(const Value &value, - lldb_private::TraceSessionFileParser::JSONAddress &address, - Path path); - -bool fromJSON(const Value &value, - lldb_private::TraceSessionFileParser::JSONModule &module, - Path path); - -bool fromJSON(const Value &value, - lldb_private::TraceSessionFileParser::JSONThread &thread, - Path path); - -bool fromJSON(const Value &value, - lldb_private::TraceSessionFileParser::JSONProcess &process, - Path path); - -bool fromJSON(const Value &value, - lldb_private::TraceSessionFileParser::JSONTracePluginSettings - &plugin_settings, - Path path); - -bool fromJSON( - const Value &value, - lldb_private::TraceSessionFileParser::JSONTraceSessionBase &session, - Path path); - -template <class TPluginSettings> -bool fromJSON( - const Value &value, - lldb_private::TraceSessionFileParser::JSONTraceSession<TPluginSettings> - &session, - Path path) { - ObjectMapper o(value, path); - return o && o.map("trace", session.trace) && - fromJSON(value, - (lldb_private::TraceSessionFileParser::JSONTraceSessionBase &) - session, - path); -} - -} // namespace json -} // namespace llvm #endif // LLDB_TARGET_TRACESESSIONPARSER_H diff --git a/contrib/llvm-project/lldb/source/Plugins/Trace/common/TraceSessionSaver.cpp b/contrib/llvm-project/lldb/source/Plugins/Trace/common/TraceSessionSaver.cpp new file mode 100644 index 000000000000..8c20a3b158cd --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Trace/common/TraceSessionSaver.cpp @@ -0,0 +1,149 @@ +//===-- TraceSessionSaver.cpp ---------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "TraceSessionSaver.h" + +#include "lldb/Core/Module.h" +#include "lldb/Core/Value.h" +#include "lldb/Target/Process.h" +#include "lldb/Target/SectionLoadList.h" +#include "lldb/Target/Target.h" +#include "lldb/lldb-types.h" +#include "llvm/Support/Error.h" +#include "llvm/Support/JSON.h" + +#include <fstream> + +using namespace lldb; +using namespace lldb_private; +using namespace llvm; + +llvm::Error TraceSessionSaver::WriteSessionToFile( + const llvm::json::Value &trace_session_description, FileSpec directory) { + + FileSpec trace_path = directory; + trace_path.AppendPathComponent("trace.json"); + std::ofstream os(trace_path.GetPath()); + os << std::string(formatv("{0:2}", trace_session_description)); + os.close(); + if (!os) + return createStringError(inconvertibleErrorCode(), + formatv("couldn't write to the file {0}", + trace_path.GetPath().c_str())); + return Error::success(); +} + +llvm::Expected<JSONTraceSessionBase> TraceSessionSaver::BuildProcessesSection( + Process &live_process, + std::function< + llvm::Expected<llvm::Optional<std::vector<uint8_t>>>(lldb::tid_t tid)> + raw_trace_fetcher, + FileSpec directory) { + + JSONTraceSessionBase json_session_description; + Expected<std::vector<JSONThread>> json_threads = + BuildThreadsSection(live_process, raw_trace_fetcher, directory); + if (!json_threads) + return json_threads.takeError(); + + Expected<std::vector<JSONModule>> json_modules = + BuildModulesSection(live_process, directory); + if (!json_modules) + return json_modules.takeError(); + + json_session_description.processes.push_back(JSONProcess{ + static_cast<int64_t>(live_process.GetID()), + live_process.GetTarget().GetArchitecture().GetTriple().getTriple(), + json_threads.get(), json_modules.get()}); + return json_session_description; +} + +llvm::Expected<std::vector<JSONThread>> TraceSessionSaver::BuildThreadsSection( + Process &live_process, + std::function< + llvm::Expected<llvm::Optional<std::vector<uint8_t>>>(lldb::tid_t tid)> + raw_trace_fetcher, + FileSpec directory) { + std::vector<JSONThread> json_threads; + for (ThreadSP thread_sp : live_process.Threads()) { + // resolve the directory just in case + FileSystem::Instance().Resolve(directory); + FileSpec raw_trace_path = directory; + raw_trace_path.AppendPathComponent(std::to_string(thread_sp->GetID()) + + ".trace"); + json_threads.push_back(JSONThread{static_cast<int64_t>(thread_sp->GetID()), + raw_trace_path.GetPath().c_str()}); + + llvm::Expected<llvm::Optional<std::vector<uint8_t>>> raw_trace = + raw_trace_fetcher(thread_sp->GetID()); + + if (!raw_trace) + return raw_trace.takeError(); + if (!raw_trace.get()) + continue; + + std::basic_fstream<char> raw_trace_fs = std::fstream( + raw_trace_path.GetPath().c_str(), std::ios::out | std::ios::binary); + raw_trace_fs.write(reinterpret_cast<const char *>(&raw_trace.get()->at(0)), + raw_trace.get()->size() * sizeof(uint8_t)); + raw_trace_fs.close(); + if (!raw_trace_fs) { + return createStringError(inconvertibleErrorCode(), + formatv("couldn't write to the file {0}", + raw_trace_path.GetPath().c_str())); + } + } + return json_threads; +} + +llvm::Expected<std::vector<JSONModule>> +TraceSessionSaver::BuildModulesSection(Process &live_process, + FileSpec directory) { + std::vector<JSONModule> json_modules; + ModuleList module_list = live_process.GetTarget().GetImages(); + for (size_t i = 0; i < module_list.GetSize(); ++i) { + ModuleSP module_sp(module_list.GetModuleAtIndex(i)); + if (!module_sp) + continue; + std::string system_path = module_sp->GetPlatformFileSpec().GetPath(); + // TODO: support memory-only libraries like [vdso] + if (!module_sp->GetFileSpec().IsAbsolute()) + continue; + + std::string file = module_sp->GetFileSpec().GetPath(); + ObjectFile *objfile = module_sp->GetObjectFile(); + if (objfile == nullptr) + continue; + + lldb::addr_t load_addr = LLDB_INVALID_ADDRESS; + Address base_addr(objfile->GetBaseAddress()); + if (base_addr.IsValid() && + !live_process.GetTarget().GetSectionLoadList().IsEmpty()) + load_addr = base_addr.GetLoadAddress(&live_process.GetTarget()); + + if (load_addr == LLDB_INVALID_ADDRESS) + continue; + + FileSystem::Instance().Resolve(directory); + FileSpec path_to_copy_module = directory; + path_to_copy_module.AppendPathComponent("modules"); + path_to_copy_module.AppendPathComponent(system_path); + sys::fs::create_directories(path_to_copy_module.GetDirectory().AsCString()); + + if (std::error_code ec = llvm::sys::fs::copy_file( + system_path, path_to_copy_module.GetPath())) + return createStringError( + inconvertibleErrorCode(), + formatv("couldn't write to the file. {0}", ec.message())); + + json_modules.push_back( + JSONModule{system_path, path_to_copy_module.GetPath(), + JSONAddress{load_addr}, module_sp->GetUUID().GetAsString()}); + } + return json_modules; +} diff --git a/contrib/llvm-project/lldb/source/Plugins/Trace/common/TraceSessionSaver.h b/contrib/llvm-project/lldb/source/Plugins/Trace/common/TraceSessionSaver.h new file mode 100644 index 000000000000..9a1a75c167dc --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Trace/common/TraceSessionSaver.h @@ -0,0 +1,112 @@ +//===-- SessionSaver.h ----------------------------------------*- C++ //-*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_TARGET_TRACESESSIONSAVER_H +#define LLDB_TARGET_TRACESESSIONSAVER_H + +#include "TraceJSONStructs.h" + +namespace lldb_private { + +class TraceSessionSaver { + +public: + /// Save the trace session description JSON object inside the given directory + /// as a file named \a trace.json. + /// + /// \param[in] trace_session_description + /// The trace's session, as JSON Object. + /// + /// \param[in] directory + /// The directory where the JSON file will be saved. + /// + /// \return + /// \a llvm::success if the operation was successful, or an \a llvm::Error + /// otherwise. + static llvm::Error + WriteSessionToFile(const llvm::json::Value &trace_session_description, + FileSpec directory); + + /// Build the processes section of the trace session description file. Besides + /// returning the processes information, this method saves to disk all modules + /// and raw traces corresponding to the traced threads of the given process. + /// + /// \param[in] live_process + /// The process being traced. + /// + /// \param[in] raw_trace_fetcher + /// Callback function that receives a thread ID and returns its raw trace. + /// This callback should return \a None if the thread is not being traced. + /// Otherwise, it should return the raw trace in bytes or an + /// \a llvm::Error in case of failures. + /// + /// \param[in] directory + /// The directory where files will be saved when building the processes + /// section. + /// + /// \return + /// The processes section or \a llvm::Error in case of failures. + static llvm::Expected<JSONTraceSessionBase> BuildProcessesSection( + Process &live_process, + std::function< + llvm::Expected<llvm::Optional<std::vector<uint8_t>>>(lldb::tid_t tid)> + raw_trace_fetcher, + FileSpec directory); + + /// Build the threads sub-section of the trace session description file. + /// For each traced thread, its raw trace is also written to the file + /// \a thread_id_.trace inside of the given directory. + /// + /// \param[in] live_process + /// The process being traced. + /// + /// \param[in] raw_trace_fetcher + /// Callback function that receives a thread ID and returns its raw trace. + /// This callback should return \a None if the thread is not being traced. + /// Otherwise, it should return the raw trace in bytes or an + /// \a llvm::Error in case of failures. + /// + /// \param[in] directory + /// The directory where files will be saved when building the threads + /// section. + /// + /// \return + /// The threads section or \a llvm::Error in case of failures. + static llvm::Expected<std::vector<JSONThread>> BuildThreadsSection( + Process &live_process, + std::function< + llvm::Expected<llvm::Optional<std::vector<uint8_t>>>(lldb::tid_t tid)> + raw_trace_fetcher, + FileSpec directory); + + /// Build modules sub-section of the trace's session. The original modules + /// will be copied over to the \a <directory/modules> folder. Invalid modules + /// are skipped. + /// Copying the modules has the benefit of making these trace session + /// directories self-contained, as the raw traces and modules are part of the + /// output directory and can be sent to another machine, where lldb can load + /// them and replicate exactly the same trace session. + /// + /// \param[in] live_process + /// The process being traced. + /// + /// \param[in] directory + /// The directory where the modules files will be saved when building + /// the modules section. + /// Example: If a module \a libbar.so exists in the path + /// \a /usr/lib/foo/libbar.so, then it will be copied to + /// \a <directory>/modules/usr/lib/foo/libbar.so. + /// + /// \return + /// The modules section or \a llvm::Error in case of failures. + static llvm::Expected<std::vector<JSONModule>> + BuildModulesSection(Process &live_process, FileSpec directory); +}; +} // namespace lldb_private + +#endif // LLDB_TARGET_TRACESESSIONSAVER_H diff --git a/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.cpp b/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.cpp index c12bcd3523e3..6ec957771e47 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.cpp @@ -13,9 +13,11 @@ #include "DecodedThread.h" #include "TraceIntelPTConstants.h" #include "TraceIntelPTSessionFileParser.h" +#include "TraceIntelPTSessionSaver.h" #include "lldb/Core/PluginManager.h" #include "lldb/Target/Process.h" #include "lldb/Target/Target.h" +#include "llvm/ADT/None.h" using namespace lldb; using namespace lldb_private; @@ -47,25 +49,17 @@ void TraceIntelPT::Terminate() { PluginManager::UnregisterPlugin(CreateInstanceForSessionFile); } -ConstString TraceIntelPT::GetPluginNameStatic() { - static ConstString g_name("intel-pt"); - return g_name; -} - StringRef TraceIntelPT::GetSchema() { return TraceIntelPTSessionFileParser::GetSchema(); } -//------------------------------------------------------------------ -// PluginInterface protocol -//------------------------------------------------------------------ - -ConstString TraceIntelPT::GetPluginName() { return GetPluginNameStatic(); } - -uint32_t TraceIntelPT::GetPluginVersion() { return 1; } - void TraceIntelPT::Dump(Stream *s) const {} +llvm::Error TraceIntelPT::SaveLiveTraceToDisk(FileSpec directory) { + RefreshLiveProcessState(); + return TraceIntelPTSessionSaver().SaveToDisk(*this, directory); +} + Expected<TraceSP> TraceIntelPT::CreateInstanceForSessionFile( const json::Value &trace_session_file, StringRef session_file_dir, Debugger &debugger) { @@ -86,7 +80,8 @@ TraceIntelPT::TraceIntelPT( : m_cpu_info(cpu_info) { for (const ThreadPostMortemTraceSP &thread : traced_threads) m_thread_decoders.emplace( - thread.get(), std::make_unique<PostMortemThreadDecoder>(thread, *this)); + thread->GetID(), + std::make_unique<PostMortemThreadDecoder>(thread, *this)); } DecodedThreadSP TraceIntelPT::Decode(Thread &thread) { @@ -96,7 +91,7 @@ DecodedThreadSP TraceIntelPT::Decode(Thread &thread) { thread.shared_from_this(), createStringError(inconvertibleErrorCode(), *m_live_refresh_error)); - auto it = m_thread_decoders.find(&thread); + auto it = m_thread_decoders.find(thread.GetID()); if (it == m_thread_decoders.end()) return std::make_shared<DecodedThread>( thread.shared_from_this(), @@ -120,7 +115,7 @@ void TraceIntelPT::DumpTraceInfo(Thread &thread, Stream &s, bool verbose) { } Optional<size_t> TraceIntelPT::GetRawTraceSize(Thread &thread) { - if (IsTraced(thread)) + if (IsTraced(thread.GetID())) return Decode(thread)->GetRawTraceSize(); else return None; @@ -188,6 +183,8 @@ Expected<pt_cpu> TraceIntelPT::GetCPUInfo() { return *m_cpu_info; } +Process *TraceIntelPT::GetLiveProcess() { return m_live_process; } + void TraceIntelPT::DoRefreshLiveProcessState( Expected<TraceGetStateResponse> state) { m_thread_decoders.clear(); @@ -201,13 +198,13 @@ void TraceIntelPT::DoRefreshLiveProcessState( Thread &thread = *m_live_process->GetThreadList().FindThreadByID(thread_state.tid); m_thread_decoders.emplace( - &thread, std::make_unique<LiveThreadDecoder>(thread, *this)); + thread_state.tid, std::make_unique<LiveThreadDecoder>(thread, *this)); } } -bool TraceIntelPT::IsTraced(const Thread &thread) { +bool TraceIntelPT::IsTraced(lldb::tid_t tid) { RefreshLiveProcessState(); - return m_thread_decoders.count(&thread); + return m_thread_decoders.count(tid); } // The information here should match the description of the intel-pt section @@ -276,7 +273,7 @@ Error TraceIntelPT::Start(size_t thread_buffer_size, request.processBufferSizeLimit = total_buffer_size_limit; request.enableTsc = enable_tsc; request.psbPeriod = psb_period.map([](size_t val) { return (int64_t)val; }); - request.type = GetPluginName().AsCString(); + request.type = GetPluginName().str(); return Trace::Start(toJSON(request)); } @@ -310,7 +307,7 @@ llvm::Error TraceIntelPT::Start(llvm::ArrayRef<lldb::tid_t> tids, request.threadBufferSize = thread_buffer_size; request.enableTsc = enable_tsc; request.psbPeriod = psb_period.map([](size_t val) { return (int64_t)val; }); - request.type = GetPluginName().AsCString(); + request.type = GetPluginName().str(); request.tids.emplace(); for (lldb::tid_t tid : tids) request.tids->push_back(tid); diff --git a/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.h b/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.h index e3b247112ae1..a6ecf6f906b2 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.h +++ b/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.h @@ -11,6 +11,9 @@ #include "IntelPTDecoder.h" #include "TraceIntelPTSessionFileParser.h" +#include "lldb/Utility/FileSpec.h" +#include "lldb/lldb-types.h" +#include "llvm/Support/raw_ostream.h" namespace lldb_private { namespace trace_intel_pt { @@ -19,11 +22,13 @@ class TraceIntelPT : public Trace { public: void Dump(Stream *s) const override; + llvm::Error SaveLiveTraceToDisk(FileSpec directory) override; + ~TraceIntelPT() override = default; /// PluginInterface protocol /// \{ - ConstString GetPluginName() override; + llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); } static void Initialize(); @@ -52,9 +57,7 @@ public: static llvm::Expected<lldb::TraceSP> CreateInstanceForLiveProcess(Process &process); - static ConstString GetPluginNameStatic(); - - uint32_t GetPluginVersion() override; + static llvm::StringRef GetPluginNameStatic() { return "intel-pt"; } /// \} lldb::CommandObjectSP @@ -74,7 +77,7 @@ public: void DoRefreshLiveProcessState( llvm::Expected<TraceGetStateResponse> state) override; - bool IsTraced(const Thread &thread) override; + bool IsTraced(lldb::tid_t tid) override; const char *GetStartConfigurationHelp() override; @@ -139,6 +142,13 @@ public: llvm::Expected<pt_cpu> GetCPUInfo(); + /// Get the current traced live process. + /// + /// \return + /// The current traced live process. If it's not a live process, + /// return \a nullptr. + Process *GetLiveProcess(); + private: friend class TraceIntelPTSessionFileParser; @@ -170,7 +180,7 @@ private: /// It is provided by either a session file or a live process' "cpuInfo" /// binary data. llvm::Optional<pt_cpu> m_cpu_info; - std::map<const Thread *, std::unique_ptr<ThreadDecoder>> m_thread_decoders; + std::map<lldb::tid_t, std::unique_ptr<ThreadDecoder>> m_thread_decoders; /// Error gotten after a failed live process update, if any. llvm::Optional<std::string> m_live_refresh_error; }; diff --git a/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceIntelPTJSONStructs.cpp b/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceIntelPTJSONStructs.cpp new file mode 100644 index 000000000000..e36751e235dc --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceIntelPTJSONStructs.cpp @@ -0,0 +1,59 @@ +//===-- TraceIntelPTJSONStructs.cpp ---------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "TraceIntelPTJSONStructs.h" + +#include "llvm/Support/JSON.h" +#include <string> + +using namespace lldb; +using namespace lldb_private; +using namespace lldb_private::trace_intel_pt; +using namespace llvm; + +namespace llvm { +namespace json { + +bool fromJSON(const Value &value, JSONTraceIntelPTSettings &plugin_settings, + Path path) { + ObjectMapper o(value, path); + return o && o.map("cpuInfo", plugin_settings.cpuInfo) && + fromJSON(value, (JSONTracePluginSettings &)plugin_settings, path); +} + +bool fromJSON(const json::Value &value, JSONTraceIntelPTCPUInfo &cpu_info, + Path path) { + ObjectMapper o(value, path); + return o && o.map("vendor", cpu_info.vendor) && + o.map("family", cpu_info.family) && o.map("model", cpu_info.model) && + o.map("stepping", cpu_info.stepping); +} + +Value toJSON(const JSONTraceIntelPTCPUInfo &cpu_info) { + return Value(Object{{"family", cpu_info.family}, + {"model", cpu_info.model}, + {"stepping", cpu_info.stepping}, + {"vendor", cpu_info.vendor}}); +} + +llvm::json::Value toJSON(const JSONTraceIntelPTTrace &trace) { + llvm::json::Object json_trace; + json_trace["type"] = trace.type; + json_trace["cpuInfo"] = toJSON(trace.cpuInfo); + return std::move(json_trace); +} + +llvm::json::Value toJSON(const JSONTraceIntelPTSession &session) { + llvm::json::Object json_session; + json_session["trace"] = toJSON(session.ipt_trace); + json_session["processes"] = toJSON(session.session_base); + return std::move(json_session); +} + +} // namespace json +} // namespace llvm diff --git a/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceIntelPTJSONStructs.h b/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceIntelPTJSONStructs.h new file mode 100644 index 000000000000..ec024f27b8c9 --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceIntelPTJSONStructs.h @@ -0,0 +1,75 @@ +//===-- TraceIntelPTJSONStructs.h -----------------------------*- C++ //-*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_SOURCE_PLUGINS_TRACE_INTEL_PT_TRACEINTELPTJSONSTRUCTS_H +#define LLDB_SOURCE_PLUGINS_TRACE_INTEL_PT_TRACEINTELPTJSONSTRUCTS_H + +#include "../common/TraceJSONStructs.h" +#include <intel-pt.h> + +namespace lldb_private { +namespace trace_intel_pt { + +struct JSONTraceIntelPTCPUInfo { + JSONTraceIntelPTCPUInfo() = default; + + JSONTraceIntelPTCPUInfo(pt_cpu cpu_info) { + family = static_cast<int64_t>(cpu_info.family); + model = static_cast<int64_t>(cpu_info.model); + stepping = static_cast<int64_t>(cpu_info.stepping); + vendor = cpu_info.vendor == pcv_intel ? "intel" : "Unknown"; + } + + int64_t family; + int64_t model; + int64_t stepping; + std::string vendor; +}; + +struct JSONTraceIntelPTTrace { + std::string type; + JSONTraceIntelPTCPUInfo cpuInfo; +}; + +struct JSONTraceIntelPTSession { + JSONTraceIntelPTTrace ipt_trace; + JSONTraceSessionBase session_base; +}; + +struct JSONTraceIntelPTSettings : JSONTracePluginSettings { + JSONTraceIntelPTCPUInfo cpuInfo; +}; + +} // namespace trace_intel_pt +} // namespace lldb_private + +namespace llvm { +namespace json { + +bool fromJSON( + const Value &value, + lldb_private::trace_intel_pt::JSONTraceIntelPTSettings &plugin_settings, + Path path); + +bool fromJSON(const llvm::json::Value &value, + lldb_private::trace_intel_pt::JSONTraceIntelPTCPUInfo &packet, + llvm::json::Path path); + +llvm::json::Value +toJSON(const lldb_private::trace_intel_pt::JSONTraceIntelPTCPUInfo &cpu_info); + +llvm::json::Value +toJSON(const lldb_private::trace_intel_pt::JSONTraceIntelPTTrace &trace); + +llvm::json::Value +toJSON(const lldb_private::trace_intel_pt::JSONTraceIntelPTSession &session); + +} // namespace json +} // namespace llvm + +#endif // LLDB_SOURCE_PLUGINS_TRACE_INTEL_PT_TRACEINTELPTJSONSTRUCTS_H diff --git a/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceIntelPTOptions.td b/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceIntelPTOptions.td index 9e8cab1ee5c4..714a13b6e5e0 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceIntelPTOptions.td +++ b/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceIntelPTOptions.td @@ -72,3 +72,13 @@ let Command = "process trace start intel pt" in { "packets as: 2 ^ (value + 11), e.g. value 3 means 16KiB between PSB " "packets. Defaults to 0 if supported.">; } + +let Command = "process trace save intel pt" in { + def process_trace_save_intel_directory: Option<"directory", "d">, + Group<1>, + Arg<"Value">, Required, + Desc<"This value defines the directory where the trace will be saved." + "It will be created if it does not exist. It will also create a " + "trace files with the trace data and a trace.json with the main " + "properties of the trace session.">; +} diff --git a/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceIntelPTSessionFileParser.cpp b/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceIntelPTSessionFileParser.cpp index 5af7c269d0cb..7e2c39a20255 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceIntelPTSessionFileParser.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceIntelPTSessionFileParser.cpp @@ -9,10 +9,7 @@ #include "TraceIntelPTSessionFileParser.h" #include "../common/ThreadPostMortemTrace.h" -#include "lldb/Core/Debugger.h" -#include "lldb/Target/Process.h" -#include "lldb/Target/Target.h" -#include "lldb/Target/ThreadList.h" +#include "TraceIntelPT.h" using namespace lldb; using namespace lldb_private; @@ -59,7 +56,7 @@ TraceSP TraceIntelPTSessionFileParser::CreateTraceIntelPTInstance( Expected<TraceSP> TraceIntelPTSessionFileParser::Parse() { json::Path::Root root("traceSession"); - TraceSessionFileParser::JSONTraceSession<JSONTraceIntelPTSettings> session; + JSONTraceSession<JSONTraceIntelPTSettings> session; if (!json::fromJSON(m_trace_session_file, session, root)) return CreateJSONError(root, m_trace_session_file); @@ -70,38 +67,3 @@ Expected<TraceSP> TraceIntelPTSessionFileParser::Parse() { else return parsed_processes.takeError(); } - -namespace llvm { -namespace json { - -bool fromJSON( - const Value &value, - TraceIntelPTSessionFileParser::JSONTraceIntelPTSettings &plugin_settings, - Path path) { - ObjectMapper o(value, path); - return o && o.map("cpuInfo", plugin_settings.cpuInfo) && - fromJSON( - value, - (TraceSessionFileParser::JSONTracePluginSettings &)plugin_settings, - path); -} - -bool fromJSON(const json::Value &value, - TraceIntelPTSessionFileParser::JSONTraceIntelPTCPUInfo &cpu_info, - Path path) { - ObjectMapper o(value, path); - return o && o.map("vendor", cpu_info.vendor) && - o.map("family", cpu_info.family) && o.map("model", cpu_info.model) && - o.map("stepping", cpu_info.stepping); -} - -Value toJSON( - const TraceIntelPTSessionFileParser::JSONTraceIntelPTCPUInfo &cpu_info) { - return Value(Object{{"family", cpu_info.family}, - {"model", cpu_info.model}, - {"stepping", cpu_info.stepping}, - {"vendor", cpu_info.vendor}}); -} - -} // namespace json -} // namespace llvm diff --git a/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceIntelPTSessionFileParser.h b/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceIntelPTSessionFileParser.h index b2667a882222..34883d3cf300 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceIntelPTSessionFileParser.h +++ b/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceIntelPTSessionFileParser.h @@ -9,9 +9,9 @@ #ifndef LLDB_SOURCE_PLUGINS_TRACE_INTEL_PT_TRACEINTELPTSESSIONFILEPARSER_H #define LLDB_SOURCE_PLUGINS_TRACE_INTEL_PT_TRACEINTELPTSESSIONFILEPARSER_H -#include "TraceIntelPT.h" - #include "../common/TraceSessionFileParser.h" +#include "TraceIntelPT.h" +#include "TraceIntelPTJSONStructs.h" namespace lldb_private { namespace trace_intel_pt { @@ -20,17 +20,6 @@ class TraceIntelPT; class TraceIntelPTSessionFileParser : public TraceSessionFileParser { public: - struct JSONTraceIntelPTCPUInfo { - int64_t family; - int64_t model; - int64_t stepping; - std::string vendor; - }; - - struct JSONTraceIntelPTSettings - : TraceSessionFileParser::JSONTracePluginSettings { - JSONTraceIntelPTCPUInfo cpuInfo; - }; /// See \a TraceSessionFileParser::TraceSessionFileParser for the description /// of these fields. @@ -65,24 +54,5 @@ private: } // namespace trace_intel_pt } // namespace lldb_private -namespace llvm { -namespace json { - -bool fromJSON(const Value &value, - lldb_private::trace_intel_pt::TraceIntelPTSessionFileParser:: - JSONTraceIntelPTSettings &plugin_settings, - Path path); - -bool fromJSON(const llvm::json::Value &value, - lldb_private::trace_intel_pt::TraceIntelPTSessionFileParser:: - JSONTraceIntelPTCPUInfo &packet, - llvm::json::Path path); - -llvm::json::Value -toJSON(const lldb_private::trace_intel_pt::TraceIntelPTSessionFileParser:: - JSONTraceIntelPTCPUInfo &packet); - -} // namespace json -} // namespace llvm #endif // LLDB_SOURCE_PLUGINS_TRACE_INTEL_PT_TRACEINTELPTSESSIONFILEPARSER_H diff --git a/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceIntelPTSessionSaver.cpp b/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceIntelPTSessionSaver.cpp new file mode 100644 index 000000000000..a8d03db1c25c --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceIntelPTSessionSaver.cpp @@ -0,0 +1,79 @@ +//===-- TraceIntelPTSessionSaver.cpp --------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "TraceIntelPTSessionSaver.h" +#include "../common/TraceSessionSaver.h" +#include "TraceIntelPT.h" +#include "TraceIntelPTJSONStructs.h" +#include "lldb/Core/Module.h" +#include "lldb/Core/ModuleList.h" +#include "lldb/Target/Process.h" +#include "lldb/Target/SectionLoadList.h" +#include "lldb/Target/Target.h" +#include "lldb/Target/ThreadList.h" +#include "lldb/lldb-types.h" +#include "llvm/ADT/None.h" +#include "llvm/Support/Error.h" +#include "llvm/Support/JSON.h" + +#include <fstream> +#include <iostream> +#include <sstream> +#include <string> + +using namespace lldb; +using namespace lldb_private; +using namespace lldb_private::trace_intel_pt; +using namespace llvm; + +llvm::Error TraceIntelPTSessionSaver::SaveToDisk(TraceIntelPT &trace_ipt, + FileSpec directory) { + Process *live_process = trace_ipt.GetLiveProcess(); + if (live_process == nullptr) + return createStringError(inconvertibleErrorCode(), + "Saving a trace requires a live process."); + + if (std::error_code ec = + sys::fs::create_directories(directory.GetPath().c_str())) + return llvm::errorCodeToError(ec); + + llvm::Expected<JSONTraceIntelPTTrace> json_intel_pt_trace = + BuildTraceSection(trace_ipt); + if (!json_intel_pt_trace) + return json_intel_pt_trace.takeError(); + + llvm::Expected<JSONTraceSessionBase> json_session_description = + TraceSessionSaver::BuildProcessesSection( + *live_process, + [&](lldb::tid_t tid) + -> llvm::Expected<llvm::Optional<std::vector<uint8_t>>> { + if (!trace_ipt.IsTraced(tid)) + return None; + return trace_ipt.GetLiveThreadBuffer(tid); + }, + directory); + + if (!json_session_description) + return json_session_description.takeError(); + + JSONTraceIntelPTSession json_intel_pt_session{json_intel_pt_trace.get(), + json_session_description.get()}; + + return TraceSessionSaver::WriteSessionToFile( + llvm::json::toJSON(json_intel_pt_session), directory); +} + +llvm::Expected<JSONTraceIntelPTTrace> +TraceIntelPTSessionSaver::BuildTraceSection(TraceIntelPT &trace_ipt) { + llvm::Expected<pt_cpu> cpu_info = trace_ipt.GetCPUInfo(); + if (!cpu_info) + return cpu_info.takeError(); + + return JSONTraceIntelPTTrace{"intel-pt", + JSONTraceIntelPTCPUInfo(cpu_info.get())}; +} diff --git a/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceIntelPTSessionSaver.h b/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceIntelPTSessionSaver.h new file mode 100644 index 000000000000..943519f959e9 --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Trace/intel-pt/TraceIntelPTSessionSaver.h @@ -0,0 +1,57 @@ +//===-- TraceIntelPTSessionSaver.h ---------------------------*- C++ //-*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_SOURCE_PLUGINS_TRACE_INTEL_PT_TRACEINTELPTSESSIONSAVER_H +#define LLDB_SOURCE_PLUGINS_TRACE_INTEL_PT_TRACEINTELPTSESSIONSAVER_H + +#include "TraceIntelPT.h" + +#include "../common/TraceJSONStructs.h" + +namespace lldb_private { +namespace trace_intel_pt { + +class TraceIntelPT; + +class TraceIntelPTSessionSaver { + +public: + /// Save the Intel PT trace of a live process to the specified directory, + /// which will be created if needed. This will also create a file + /// \a <directory>/trace.json with the main properties of the trace + /// session, along with others files which contain the actual trace data. + /// The trace.json file can be used later as input for the "trace load" + /// command to load the trace in LLDB. + /// + /// \param[in] trace_ipt + /// The Intel PT trace to be saved to disk. + /// + /// \param[in] directory + /// The directory where the trace files will be saved. + /// + /// \return + /// \a llvm::success if the operation was successful, or an \a llvm::Error + /// otherwise. + llvm::Error SaveToDisk(TraceIntelPT &trace_ipt, FileSpec directory); + +private: + /// Build trace section of the intel-pt trace session description file. + /// + /// \param[in] trace_ipt + /// The Intel PT trace. + /// + /// \return + /// The trace section an \a llvm::Error in case of failures. + llvm::Expected<JSONTraceIntelPTTrace> + BuildTraceSection(TraceIntelPT &trace_ipt); +}; + +} // namespace trace_intel_pt +} // namespace lldb_private + +#endif // LLDB_SOURCE_PLUGINS_TRACE_INTEL_PT_TRACEINTELPTSESSIONSAVER_H diff --git a/contrib/llvm-project/lldb/source/Plugins/TraceExporter/common/TraceHTR.cpp b/contrib/llvm-project/lldb/source/Plugins/TraceExporter/common/TraceHTR.cpp new file mode 100644 index 000000000000..d29445cc004f --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/TraceExporter/common/TraceHTR.cpp @@ -0,0 +1,485 @@ +//===-- TraceHTR.cpp ------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "TraceHTR.h" + +#include "lldb/Symbol/Function.h" +#include "lldb/Target/Process.h" +#include "lldb/Target/Target.h" +#include "llvm/Support/JSON.h" +#include <sstream> +#include <string> + +using namespace lldb_private; +using namespace lldb; + +size_t HTRBlockMetadata::GetNumInstructions() const { + return m_num_instructions; +} + +llvm::Optional<llvm::StringRef> +HTRBlockMetadata::GetMostFrequentlyCalledFunction() const { + size_t max_ncalls = 0; + llvm::Optional<llvm::StringRef> max_name = llvm::None; + for (const auto &it : m_func_calls) { + ConstString name = it.first; + size_t ncalls = it.second; + if (ncalls > max_ncalls) { + max_ncalls = ncalls; + max_name = name.GetStringRef(); + } + } + return max_name; +} + +llvm::DenseMap<ConstString, size_t> const & +HTRBlockMetadata::GetFunctionCalls() const { + return m_func_calls; +} + +lldb::addr_t HTRBlockMetadata::GetFirstInstructionLoadAddress() const { + return m_first_instruction_load_address; +} + +size_t HTRBlock::GetOffset() const { return m_offset; } + +size_t HTRBlock::GetSize() const { return m_size; } + +HTRBlockMetadata const &HTRBlock::GetMetadata() const { return m_metadata; } + +llvm::ArrayRef<HTRBlockLayerUP> TraceHTR::GetBlockLayers() const { + return m_block_layer_ups; +} + +HTRInstructionLayer const &TraceHTR::GetInstructionLayer() const { + return *m_instruction_layer_up; +} + +void TraceHTR::AddNewBlockLayer(HTRBlockLayerUP &&block_layer) { + m_block_layer_ups.emplace_back(std::move(block_layer)); +} + +size_t IHTRLayer::GetLayerId() const { return m_layer_id; } + +void HTRBlockLayer::AppendNewBlock(size_t block_id, HTRBlock &&block) { + m_block_id_trace.emplace_back(block_id); + m_block_defs.emplace(block_id, block); +} + +void HTRBlockLayer::AppendRepeatedBlock(size_t block_id) { + m_block_id_trace.emplace_back(block_id); +} + +llvm::ArrayRef<lldb::addr_t> HTRInstructionLayer::GetInstructionTrace() const { + return m_instruction_trace; +} + +void HTRInstructionLayer::AddCallInstructionMetadata( + lldb::addr_t load_addr, llvm::Optional<ConstString> func_name) { + m_call_isns.emplace(load_addr, func_name); +} + +void HTRInstructionLayer::AppendInstruction(lldb::addr_t load_addr) { + m_instruction_trace.emplace_back(load_addr); +} + +HTRBlock const *HTRBlockLayer::GetBlockById(size_t block_id) const { + auto block_it = m_block_defs.find(block_id); + if (block_it == m_block_defs.end()) + return nullptr; + else + return &block_it->second; +} + +llvm::ArrayRef<size_t> HTRBlockLayer::GetBlockIdTrace() const { + return m_block_id_trace; +} + +size_t HTRBlockLayer::GetNumUnits() const { return m_block_id_trace.size(); } + +HTRBlockMetadata HTRInstructionLayer::GetMetadataByIndex(size_t index) const { + lldb::addr_t instruction_load_address = m_instruction_trace[index]; + llvm::DenseMap<ConstString, size_t> func_calls; + + auto func_name_it = m_call_isns.find(instruction_load_address); + if (func_name_it != m_call_isns.end()) { + if (llvm::Optional<ConstString> func_name = func_name_it->second) { + func_calls[*func_name] = 1; + } + } + return {instruction_load_address, 1, std::move(func_calls)}; +} + +size_t HTRInstructionLayer::GetNumUnits() const { + return m_instruction_trace.size(); +} + +HTRBlockMetadata HTRBlockLayer::GetMetadataByIndex(size_t index) const { + size_t block_id = m_block_id_trace[index]; + HTRBlock block = m_block_defs.find(block_id)->second; + return block.GetMetadata(); +} + +TraceHTR::TraceHTR(Thread &thread, TraceCursor &cursor) + : m_instruction_layer_up(std::make_unique<HTRInstructionLayer>(0)) { + + // Move cursor to the first instruction in the trace + cursor.SetForwards(true); + cursor.Seek(0, TraceCursor::SeekType::Set); + + Target &target = thread.GetProcess()->GetTarget(); + auto function_name_from_load_address = + [&](lldb::addr_t load_address) -> llvm::Optional<ConstString> { + lldb_private::Address pc_addr; + SymbolContext sc; + if (target.ResolveLoadAddress(load_address, pc_addr) && + pc_addr.CalculateSymbolContext(&sc)) + return sc.GetFunctionName() + ? llvm::Optional<ConstString>(sc.GetFunctionName()) + : llvm::None; + else + return llvm::None; + }; + + bool more_data_in_trace = true; + while (more_data_in_trace) { + if (cursor.IsError()) { + // Append a load address of 0 for all instructions that an error occured + // while decoding. + // TODO: Make distinction between errors by storing the error messages. + // Currently, all errors are treated the same. + m_instruction_layer_up->AppendInstruction(0); + more_data_in_trace = cursor.Next(); + } else { + lldb::addr_t current_instruction_load_address = cursor.GetLoadAddress(); + lldb::TraceInstructionControlFlowType current_instruction_type = + cursor.GetInstructionControlFlowType(); + + m_instruction_layer_up->AppendInstruction( + current_instruction_load_address); + more_data_in_trace = cursor.Next(); + if (current_instruction_type & + lldb::eTraceInstructionControlFlowTypeCall) { + if (more_data_in_trace && !cursor.IsError()) { + m_instruction_layer_up->AddCallInstructionMetadata( + current_instruction_load_address, + function_name_from_load_address(cursor.GetLoadAddress())); + } else { + // Next instruction is not known - pass None to indicate the name + // of the function being called is not known + m_instruction_layer_up->AddCallInstructionMetadata( + current_instruction_load_address, llvm::None); + } + } + } + } +} + +void HTRBlockMetadata::MergeMetadata( + HTRBlockMetadata &merged_metadata, + HTRBlockMetadata const &metadata_to_merge) { + merged_metadata.m_num_instructions += metadata_to_merge.m_num_instructions; + for (const auto &it : metadata_to_merge.m_func_calls) { + ConstString name = it.first; + size_t num_calls = it.second; + merged_metadata.m_func_calls[name] += num_calls; + } +} + +HTRBlock IHTRLayer::MergeUnits(size_t start_unit_index, size_t num_units) { + // TODO: make this function take `end_unit_index` as a parameter instead of + // unit and merge the range [start_unit_indx, end_unit_index] inclusive. + HTRBlockMetadata merged_metadata = GetMetadataByIndex(start_unit_index); + for (size_t i = start_unit_index + 1; i < start_unit_index + num_units; i++) { + // merge the new metadata into merged_metadata + HTRBlockMetadata::MergeMetadata(merged_metadata, GetMetadataByIndex(i)); + } + return {start_unit_index, num_units, merged_metadata}; +} + +void TraceHTR::ExecutePasses() { + auto are_passes_done = [](IHTRLayer &l1, IHTRLayer &l2) { + return l1.GetNumUnits() == l2.GetNumUnits(); + }; + HTRBlockLayerUP current_block_layer_up = + BasicSuperBlockMerge(*m_instruction_layer_up); + HTRBlockLayer ¤t_block_layer = *current_block_layer_up; + if (are_passes_done(*m_instruction_layer_up, *current_block_layer_up)) + return; + + AddNewBlockLayer(std::move(current_block_layer_up)); + while (true) { + HTRBlockLayerUP new_block_layer_up = + BasicSuperBlockMerge(current_block_layer); + if (are_passes_done(current_block_layer, *new_block_layer_up)) + return; + + current_block_layer = *new_block_layer_up; + AddNewBlockLayer(std::move(new_block_layer_up)); + } +} + +llvm::Error TraceHTR::Export(std::string outfile) { + std::error_code ec; + llvm::raw_fd_ostream os(outfile, ec, llvm::sys::fs::OF_Text); + if (ec) { + return llvm::make_error<llvm::StringError>( + "unable to open destination file: " + outfile, os.error()); + } else { + os << toJSON(*this); + os.close(); + if (os.has_error()) { + return llvm::make_error<llvm::StringError>( + "unable to write to destination file: " + outfile, os.error()); + } + } + return llvm::Error::success(); +} + +HTRBlockLayerUP lldb_private::BasicSuperBlockMerge(IHTRLayer &layer) { + std::unique_ptr<HTRBlockLayer> new_block_layer = + std::make_unique<HTRBlockLayer>(layer.GetLayerId() + 1); + + if (layer.GetNumUnits()) { + // Future Improvement: split this into two functions - one for finding heads + // and tails, one for merging/creating the next layer A 'head' is defined to + // be a block whose occurrences in the trace do not have a unique preceding + // block. + std::unordered_set<size_t> heads; + + // The load address of the first instruction of a block is the unique ID for + // that block (i.e. blocks with the same first instruction load address are + // the same block) + + // Future Improvement: no need to store all its preceding block ids, all we + // care about is that there is more than one preceding block id, so an enum + // could be used + std::unordered_map<lldb::addr_t, std::unordered_set<lldb::addr_t>> head_map; + lldb::addr_t prev_id = + layer.GetMetadataByIndex(0).GetFirstInstructionLoadAddress(); + size_t num_units = layer.GetNumUnits(); + // This excludes the first unit since it has no previous unit + for (size_t i = 1; i < num_units; i++) { + lldb::addr_t current_id = + layer.GetMetadataByIndex(i).GetFirstInstructionLoadAddress(); + head_map[current_id].insert(prev_id); + prev_id = current_id; + } + for (const auto &it : head_map) { + // ID of 0 represents an error - errors can't be heads or tails + lldb::addr_t id = it.first; + const std::unordered_set<lldb::addr_t> predecessor_set = it.second; + if (id && predecessor_set.size() > 1) + heads.insert(id); + } + + // Future Improvement: identify heads and tails in the same loop + // A 'tail' is defined to be a block whose occurrences in the trace do + // not have a unique succeeding block. + std::unordered_set<lldb::addr_t> tails; + std::unordered_map<lldb::addr_t, std::unordered_set<lldb::addr_t>> tail_map; + + // This excludes the last unit since it has no next unit + for (size_t i = 0; i < num_units - 1; i++) { + lldb::addr_t current_id = + layer.GetMetadataByIndex(i).GetFirstInstructionLoadAddress(); + lldb::addr_t next_id = + layer.GetMetadataByIndex(i + 1).GetFirstInstructionLoadAddress(); + tail_map[current_id].insert(next_id); + } + + // Mark last block as tail so the algorithm stops gracefully + lldb::addr_t last_id = layer.GetMetadataByIndex(num_units - 1) + .GetFirstInstructionLoadAddress(); + tails.insert(last_id); + for (const auto &it : tail_map) { + lldb::addr_t id = it.first; + const std::unordered_set<lldb::addr_t> successor_set = it.second; + // ID of 0 represents an error - errors can't be heads or tails + if (id && successor_set.size() > 1) + tails.insert(id); + } + + // Need to keep track of size of string since things we push are variable + // length + size_t superblock_size = 0; + // Each super block always has the same first unit (we call this the + // super block head) This gurantee allows us to use the super block head as + // the unique key mapping to the super block it begins + llvm::Optional<size_t> superblock_head = llvm::None; + auto construct_next_layer = [&](size_t merge_start, size_t n) -> void { + if (!superblock_head) + return; + if (new_block_layer->GetBlockById(*superblock_head)) { + new_block_layer->AppendRepeatedBlock(*superblock_head); + } else { + HTRBlock new_block = layer.MergeUnits(merge_start, n); + new_block_layer->AppendNewBlock(*superblock_head, std::move(new_block)); + } + }; + + for (size_t i = 0; i < num_units; i++) { + lldb::addr_t unit_id = + layer.GetMetadataByIndex(i).GetFirstInstructionLoadAddress(); + auto isHead = heads.count(unit_id) > 0; + auto isTail = tails.count(unit_id) > 0; + + if (isHead && isTail) { + // Head logic + if (superblock_size) { // this handles (tail, head) adjacency - + // otherwise an empty + // block is created + // End previous super block + construct_next_layer(i - superblock_size, superblock_size); + } + // Current id is first in next super block since it's a head + superblock_head = unit_id; + superblock_size = 1; + + // Tail logic + construct_next_layer(i - superblock_size + 1, superblock_size); + // Reset the block_head since the prev super block has come to and end + superblock_head = llvm::None; + superblock_size = 0; + } else if (isHead) { + if (superblock_size) { // this handles (tail, head) adjacency - + // otherwise an empty + // block is created + // End previous super block + construct_next_layer(i - superblock_size, superblock_size); + } + // Current id is first in next super block since it's a head + superblock_head = unit_id; + superblock_size = 1; + } else if (isTail) { + if (!superblock_head) + superblock_head = unit_id; + superblock_size++; + + // End previous super block + construct_next_layer(i - superblock_size + 1, superblock_size); + // Reset the block_head since the prev super block has come to and end + superblock_head = llvm::None; + superblock_size = 0; + } else { + if (!superblock_head) + superblock_head = unit_id; + superblock_size++; + } + } + } + return new_block_layer; +} + +llvm::json::Value lldb_private::toJSON(const TraceHTR &htr) { + std::vector<llvm::json::Value> layers_as_json; + for (size_t i = 0; i < htr.GetInstructionLayer().GetInstructionTrace().size(); + i++) { + size_t layer_id = htr.GetInstructionLayer().GetLayerId(); + HTRBlockMetadata metadata = htr.GetInstructionLayer().GetMetadataByIndex(i); + lldb::addr_t load_address = metadata.GetFirstInstructionLoadAddress(); + + std::string display_name; + + std::stringstream stream; + stream << "0x" << std::hex << load_address; + std::string load_address_hex_string(stream.str()); + display_name.assign(load_address_hex_string); + + // name: load address of the first instruction of the block and the name + // of the most frequently called function from the block (if applicable) + + // ph: the event type - 'X' for Complete events (see link to documentation + // below) + + // Since trace timestamps aren't yet supported in HTR, the ts (timestamp) is + // based on the instruction's offset in the trace and the dur (duration) is + // 1 since this layer contains single instructions. Using the instruction + // offset and a duration of 1 oversimplifies the true timing information of + // the trace, nonetheless, these approximate timestamps/durations provide an + // clear visualization of the trace. + + // ts: offset from the beginning of the trace for the first instruction in + // the block + + // dur: 1 since this layer contains single instructions. + + // pid: the ID of the HTR layer the blocks belong to + + // See + // https://docs.google.com/document/d/1CvAClvFfyA5R-PhYUmn5OOQtYMH4h6I0nSsKchNAySU/preview#heading=h.j75x71ritcoy + // for documentation on the Trace Event Format + layers_as_json.emplace_back(llvm::json::Object{ + {"name", display_name}, + {"ph", "X"}, + {"ts", (int64_t)i}, + {"dur", 1}, + {"pid", (int64_t)layer_id}, + }); + } + + for (const auto &layer : htr.GetBlockLayers()) { + size_t start_ts = 0; + std::vector<size_t> block_id_trace = layer->GetBlockIdTrace(); + for (size_t i = 0; i < block_id_trace.size(); i++) { + size_t id = block_id_trace[i]; + // Guranteed that this ID is valid, so safe to dereference here. + HTRBlock block = *layer->GetBlockById(id); + llvm::json::Value block_json = toJSON(block); + size_t layer_id = layer->GetLayerId(); + + HTRBlockMetadata metadata = block.GetMetadata(); + + llvm::Optional<llvm::StringRef> most_freq_func = + metadata.GetMostFrequentlyCalledFunction(); + std::stringstream stream; + stream << "0x" << std::hex << metadata.GetFirstInstructionLoadAddress(); + std::string offset_hex_string(stream.str()); + std::string display_name = + most_freq_func ? offset_hex_string + ": " + most_freq_func->str() + : offset_hex_string; + + // Since trace timestamps aren't yet supported in HTR, the ts (timestamp) + // and dur (duration) are based on the block's offset in the trace and + // number of instructions in the block, respectively. Using the block + // offset and the number of instructions oversimplifies the true timing + // information of the trace, nonetheless, these approximate + // timestamps/durations provide an understandable visualization of the + // trace. + auto duration = metadata.GetNumInstructions(); + layers_as_json.emplace_back(llvm::json::Object{ + {"name", display_name}, + {"ph", "X"}, + {"ts", (int64_t)start_ts}, + {"dur", (int64_t)duration}, + {"pid", (int64_t)layer_id}, + {"args", block_json}, + }); + start_ts += duration; + } + } + return layers_as_json; +} + +llvm::json::Value lldb_private::toJSON(const HTRBlock &block) { + return llvm::json::Value( + llvm::json::Object{{"Metadata", block.GetMetadata()}}); +} + +llvm::json::Value lldb_private::toJSON(const HTRBlockMetadata &metadata) { + std::vector<llvm::json::Value> function_calls; + for (const auto &it : metadata.GetFunctionCalls()) { + ConstString name = it.first; + size_t n_calls = it.second; + function_calls.emplace_back(llvm::formatv("({0}: {1})", name, n_calls)); + } + + return llvm::json::Value(llvm::json::Object{ + {"Number of Instructions", (ssize_t)metadata.GetNumInstructions()}, + {"Functions", function_calls}}); +} diff --git a/contrib/llvm-project/lldb/source/Plugins/TraceExporter/common/TraceHTR.h b/contrib/llvm-project/lldb/source/Plugins/TraceExporter/common/TraceHTR.h new file mode 100644 index 000000000000..03babc5a36ab --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/TraceExporter/common/TraceHTR.h @@ -0,0 +1,409 @@ +//===-- TraceHTR.h --------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache +// License v2.0 with LLVM Exceptions.// See https://llvm.org/LICENSE.txt for +// license information.// SPDX-License-Identifier: Apache-2.0 WITH +// LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_TARGET_TRACE_HTR_H +#define LLDB_TARGET_TRACE_HTR_H + +#include "lldb/Target/Thread.h" +#include "lldb/Target/Trace.h" + +#include <unordered_map> +#include <unordered_set> + +namespace lldb_private { + +/// Metadata associated with an HTR block +/// See lldb/docs/htr.rst for comprehensive HTR documentation +class HTRBlockMetadata { +public: + /// Constructor for a block's metadata. + /// + /// \param[in] first_instruction_load_address + /// The load address of the block's first instruction. + /// + /// \param[in] num_instructions + /// The total number of instructions in the block. + /// + /// \param[in] func_calls + /// The map of a function name to the number of times it is called from + /// the block. + HTRBlockMetadata(lldb::addr_t first_instruction_load_address, + size_t num_instructions, + llvm::DenseMap<ConstString, size_t> &&func_calls) + : m_first_instruction_load_address(first_instruction_load_address), + m_num_instructions(num_instructions), m_func_calls(func_calls) {} + + /// Merge two \a HTRBlockMetadata in place. + /// + /// \param[in][out] merged_metadata + /// Metadata that metadata_to_merge will be merged into. + /// + /// \param[in] metadata_to_merge + /// Metadata to merge into merged_metadata. + static void MergeMetadata(HTRBlockMetadata &merged_metadata, + HTRBlockMetadata const &metadata_to_merge); + /// Get the number of instructions in the block. + /// + /// \return + /// The number of instructions in the block. + size_t GetNumInstructions() const; + + /// Get the name of the most frequently called function from the block. + /// + /// \return + /// The name of the function that is called the most from this block or + /// None if no function is called from this block. + llvm::Optional<llvm::StringRef> GetMostFrequentlyCalledFunction() const; + + /// Get the load address of the first instruction in the block. + /// + /// \return + /// The load address of the first instruction in the block. + lldb::addr_t GetFirstInstructionLoadAddress() const; + + /// Get the function calls map for the block. + /// Function calls are identified in the instruction layer by finding 'call' + /// instructions and determining the function they are calling. As these + /// instructions are merged into blocks, we merge these different function + /// calls into a single map containing the function names to the number of + /// times it is called from this block. + /// + /// \return + /// The mapping of function name to the number of times it is called from + /// this block. + llvm::DenseMap<ConstString, size_t> const &GetFunctionCalls() const; + +private: + lldb::addr_t m_first_instruction_load_address; + size_t m_num_instructions; + llvm::DenseMap<ConstString, size_t> m_func_calls; +}; + +/// Block structure representing a sequence of trace "units" (ie instructions). +/// Sequences of blocks are merged to create a new, single block +/// See lldb/docs/htr.rst for comprehensive HTR documentation +class HTRBlock { +public: + /// Constructor for a block of an HTR layer. + /// + /// \param[in] offset + /// The offset of the start of this block in the previous layer. + /// + /// \param[in] size + /// Number of blocks/instructions that make up this block in the previous + /// layer. + /// + /// \param[in] metadata + /// General metadata for this block. + HTRBlock(size_t offset, size_t size, HTRBlockMetadata metadata) + : m_offset(offset), m_size(size), m_metadata(metadata) {} + + /// Get the offset of the start of this block in the previous layer. + /// + /// \return + /// The offset of the block. + size_t GetOffset() const; + + /// Get the number of blocks/instructions that make up this block in the + /// previous layer. + /// + /// \return + /// The size of the block. + size_t GetSize() const; + + /// Get the metadata for this block. + /// + /// \return + /// The metadata of the block. + HTRBlockMetadata const &GetMetadata() const; + +private: + /// Offset in the previous layer + size_t m_offset; + /// Number of blocks/instructions that make up this block in the previous + /// layer + size_t m_size; + /// General metadata for this block + HTRBlockMetadata m_metadata; +}; + +/// HTR layer interface +/// See lldb/docs/htr.rst for comprehensive HTR documentation +class IHTRLayer { +public: + /// Construct new HTR layer. + // + /// \param[in] id + /// The layer's id. + IHTRLayer(size_t id) : m_layer_id(id) {} + + /// Get the ID of the layer. + /// + /// \return + /// The layer ID of this layer. + size_t GetLayerId() const; + + /// Get the metadata of a unit (instruction or block) in the layer. + /// + /// \param[in] index + /// The position of the unit in the layer. + /// + /// \return + /// The metadata of the unit in the layer. + virtual HTRBlockMetadata GetMetadataByIndex(size_t index) const = 0; + + /// Get the total number of units (instruction or block) in this layer. + /// + /// \return + /// The total number of units in the layer. + virtual size_t GetNumUnits() const = 0; + + /// Creates a new block from the result of merging a contiguous sequence of + /// "units" (instructions or blocks depending on layer type) in this layer + /// This allows the implementation class to decide how to store/generate this + /// metadata. For example, in the case of the instruction layer we want to + /// lazily generate this metadata instead of storing it for each instruction. + /// + /// \param[in] start_unit_index + /// The index of the first unit to be merged. + /// + /// \param[in] num_units + /// The number of units to be merged. Must be >= 1, since merging 0 blocks + /// does not make sense. + /// + /// \return + /// A new block instance representing the merge of the specified units. + HTRBlock MergeUnits(size_t start_unit_index, size_t num_units); + + virtual ~IHTRLayer() = default; + +protected: + /// ID of the layer. + size_t m_layer_id; +}; + +/// "Base" layer of HTR representing the dynamic instructions of the trace. +/// See lldb/docs/htr.rst for comprehensive HTR documentation +class HTRInstructionLayer : public IHTRLayer { +public: + /// Construct new instruction layer. + // + /// \param[in] id + /// The layer's id. + HTRInstructionLayer(size_t id) : IHTRLayer(id) {} + + size_t GetNumUnits() const override; + + HTRBlockMetadata GetMetadataByIndex(size_t index) const override; + + /// Get the dynamic instruction trace. + /// + /// \return + /// The dynamic instruction trace. + llvm::ArrayRef<lldb::addr_t> GetInstructionTrace() const; + + /// Add metadata for a 'call' instruction of the trace. + /// + /// \param[in] load_addr + /// The load address of the 'call' instruction. + /// + /// \param[in] func_name + /// The name of the function the 'call' instruction is calling if it can + /// be determined, None otherwise. + void AddCallInstructionMetadata(lldb::addr_t load_addr, + llvm::Optional<ConstString> func_name); + + /// Append the load address of an instruction to the dynamic instruction + /// trace. + /// + /// \param[in] load_addr + /// The load address of the instruction. + void AppendInstruction(lldb::addr_t load_addr); + +private: + // Dynamic instructions of trace are stored in chronological order. + std::vector<lldb::addr_t> m_instruction_trace; + // Only store metadata for instructions of interest (call instructions) + // If we stored metadata for each instruction this would be wasteful since + // most instructions don't contain useful metadata + + // This map contains the load address of all the call instructions. + // load address maps to the name of the function it calls (None if function + // name can't be determined) + std::unordered_map<lldb::addr_t, llvm::Optional<ConstString>> m_call_isns; +}; + +/// HTR layer composed of blocks of the trace. +/// See lldb/docs/htr.rst for comprehensive HTR documentation +class HTRBlockLayer : public IHTRLayer { +public: + /// Construct new block layer. + // + /// \param[in] id + /// The layer's id. + HTRBlockLayer(size_t id) : IHTRLayer(id) {} + + size_t GetNumUnits() const override; + + HTRBlockMetadata GetMetadataByIndex(size_t index) const override; + + /// Get an \a HTRBlock from its block id. + /// + /// \param[in] block_id + /// The id of the block to retrieve. + /// + /// \return + /// The \a HTRBlock with the specified id, nullptr if no there is no block + /// in the layer with the specified block id. + HTRBlock const *GetBlockById(size_t block_id) const; + + /// Get the block ID trace for this layer. + /// This block ID trace stores the block ID of each block that occured in the + /// trace and the block defs map maps block ID to the corresponding \a + /// HTRBlock. + /// + /// \return + /// The block ID trace for this layer. + llvm::ArrayRef<size_t> GetBlockIdTrace() const; + + /// Appends a new block to the layer. + /// + /// \param[in] block_id + /// The block id of the new block. + /// + /// \param[in] block + /// The new \a HTRBlock to be appended to the layer. This block is moved + /// into the layer. + void AppendNewBlock(size_t block_id, HTRBlock &&block); + + /// Appends a repeated block to the layer. + /// + /// \param[in] block_id + /// The block id of the repeated block. + void AppendRepeatedBlock(size_t block_id); + +private: + /// Maps a unique Block ID to the corresponding HTRBlock + std::unordered_map<size_t, HTRBlock> m_block_defs; + /// Reduce memory footprint by just storing a trace of block IDs and use + /// m_block_defs to map a block_id to its corresponding HTRBlock + std::vector<size_t> m_block_id_trace; +}; + +typedef std::unique_ptr<lldb_private::HTRBlockLayer> HTRBlockLayerUP; +typedef std::unique_ptr<lldb_private::HTRInstructionLayer> + HTRInstructionLayerUP; + +/// Top-level HTR class +/// See lldb/docs/htr.rst for comprehensive HTR documentation +class TraceHTR { + +public: + /// Constructor for a trace's HTR. + /// + /// \param[in] thread + /// The thread the trace belongs to. + /// + /// \param[in] cursor + /// The trace cursor that gives access to the trace's contents. + TraceHTR(Thread &thread, TraceCursor &cursor); + + /// Executes passes on the HTR layers until no further + /// summarization/compression is achieved + void ExecutePasses(); + + /// Export HTR layers to the specified format and outfile. + /// + /// \param[in] outfile + /// The file that the exported HTR data will be written to. + /// + /// \return + /// Success if the export is successful, Error otherwise. + llvm::Error Export(std::string outfile); + + /// Get the block layers of this HTR. + /// + /// \return + /// The block layers of this HTR. + llvm::ArrayRef<HTRBlockLayerUP> GetBlockLayers() const; + + /// Get the instruction layer of this HTR. + /// + /// \return + /// The instruction layer of this HTR. + HTRInstructionLayer const &GetInstructionLayer() const; + + /// Add a new block layer to this HTR. + /// + /// \param[in] + /// The new block layer to be added. + void AddNewBlockLayer(HTRBlockLayerUP &&block_layer); + +private: + // There is a single instruction layer per HTR + HTRInstructionLayerUP m_instruction_layer_up; + // There are one or more block layers per HTR + std::vector<HTRBlockLayerUP> m_block_layer_ups; +}; + +// Serialization functions for exporting HTR to Chrome Trace Format +llvm::json::Value toJSON(const TraceHTR &htr); +llvm::json::Value toJSON(const HTRBlock &block); +llvm::json::Value toJSON(const HTRBlockMetadata &metadata); + +/// The HTR passes are defined below: + +/// Creates a new layer by merging the "basic super blocks" in the current layer +/// +/// A "basic super block" is the longest sequence of blocks that always occur in +/// the same order. (The concept is akin to “Basic Block" in compiler theory, +/// but refers to dynamic occurrences rather than CFG nodes) +/// +/// Procedure to find all basic super blocks: +// +/// - For each block, compute the number of distinct predecessor and +/// successor blocks. +/// Predecessor - the block that occurs directly before (to the left of) +/// the current block Successor - the block that occurs directly after +/// (to the right of) the current block +/// - A block with more than one distinct successor is always the start of a +/// super block, the super block will continue until the next block with +/// more than one distinct predecessor or successor. +/// +/// The implementation makes use of two terms - 'heads' and 'tails' known as +/// the 'endpoints' of a basic super block: +/// A 'head' is defined to be a block in the trace that doesn't have a +/// unique predecessor +/// A 'tail' is defined to be a block in the trace that doesn't have a +/// unique successor +/// +/// A basic super block is defined to be a sequence of blocks between two +/// endpoints +/// +/// A head represents the start of the next group, so the current group +/// ends at the block preceding the head and the next group begins with +/// this head block +/// +/// A tail represents the end of the current group, so the current group +/// ends with the tail block and the next group begins with the +/// following block. +/// +/// See lldb/docs/htr.rst for comprehensive HTR documentation +/// +/// \param[in] layer +/// The layer to execute the pass on. +/// +/// \return +/// A new layer instance representing the merge of blocks in the +/// previous layer +HTRBlockLayerUP BasicSuperBlockMerge(IHTRLayer &layer); + +} // namespace lldb_private + +#endif // LLDB_TARGET_TRACE_HTR_H diff --git a/contrib/llvm-project/lldb/source/Plugins/TraceExporter/ctf/CommandObjectThreadTraceExportCTF.cpp b/contrib/llvm-project/lldb/source/Plugins/TraceExporter/ctf/CommandObjectThreadTraceExportCTF.cpp index 3dd4c89e2777..919cdf46a5c0 100644 --- a/contrib/llvm-project/lldb/source/Plugins/TraceExporter/ctf/CommandObjectThreadTraceExportCTF.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/TraceExporter/ctf/CommandObjectThreadTraceExportCTF.cpp @@ -8,7 +8,10 @@ #include "CommandObjectThreadTraceExportCTF.h" +#include "../common/TraceHTR.h" #include "lldb/Host/OptionParser.h" +#include "lldb/Target/Process.h" +#include "lldb/Target/Trace.h" using namespace lldb; using namespace lldb_private; @@ -27,6 +30,10 @@ Status CommandObjectThreadTraceExportCTF::CommandOptions::SetOptionValue( const int short_option = m_getopt_table[option_idx].val; switch (short_option) { + case 'f': { + m_file.assign(std::string(option_arg)); + break; + } case 't': { int64_t thread_index; if (option_arg.empty() || option_arg.getAsInteger(0, thread_index) || @@ -45,6 +52,7 @@ Status CommandObjectThreadTraceExportCTF::CommandOptions::SetOptionValue( void CommandObjectThreadTraceExportCTF::CommandOptions::OptionParsingStarting( ExecutionContext *execution_context) { + m_file.clear(); m_thread_index = None; } @@ -55,12 +63,30 @@ CommandObjectThreadTraceExportCTF::CommandOptions::GetDefinitions() { bool CommandObjectThreadTraceExportCTF::DoExecute(Args &command, CommandReturnObject &result) { - Stream &s = result.GetOutputStream(); - // TODO: create an actual instance of the exporter and invoke it - if (m_options.m_thread_index) - s.Printf("got thread index %d\n", (int)m_options.m_thread_index.getValue()); - else - s.Printf("didn't get a thread index\n"); + const TraceSP &trace_sp = m_exe_ctx.GetTargetSP()->GetTrace(); + Process *process = m_exe_ctx.GetProcessPtr(); + Thread *thread = m_options.m_thread_index + ? process->GetThreadList() + .FindThreadByIndexID(*m_options.m_thread_index) + .get() + : GetDefaultThread(); - return result.Succeeded(); + if (thread == nullptr) { + const uint32_t num_threads = process->GetThreadList().GetSize(); + size_t tid = m_options.m_thread_index ? *m_options.m_thread_index + : LLDB_INVALID_THREAD_ID; + result.AppendErrorWithFormatv( + "Thread index {0} is out of range (valid values are 1 - {1}).\n", tid, + num_threads); + return false; + } else { + TraceHTR htr(*thread, *trace_sp->GetCursor(*thread)); + htr.ExecutePasses(); + if (llvm::Error err = htr.Export(m_options.m_file)) { + result.AppendErrorWithFormat("%s\n", toString(std::move(err)).c_str()); + return false; + } else { + return true; + } + } } diff --git a/contrib/llvm-project/lldb/source/Plugins/TraceExporter/ctf/CommandObjectThreadTraceExportCTF.h b/contrib/llvm-project/lldb/source/Plugins/TraceExporter/ctf/CommandObjectThreadTraceExportCTF.h index 26b068a8f8c5..c6364cfe027d 100644 --- a/contrib/llvm-project/lldb/source/Plugins/TraceExporter/ctf/CommandObjectThreadTraceExportCTF.h +++ b/contrib/llvm-project/lldb/source/Plugins/TraceExporter/ctf/CommandObjectThreadTraceExportCTF.h @@ -30,6 +30,7 @@ public: llvm::ArrayRef<OptionDefinition> GetDefinitions() override; llvm::Optional<size_t> m_thread_index; + std::string m_file; }; CommandObjectThreadTraceExportCTF(CommandInterpreter &interpreter) @@ -39,7 +40,8 @@ public: "thread trace export ctf [<ctf-options>]", lldb::eCommandRequiresProcess | lldb::eCommandTryTargetAPILock | lldb::eCommandProcessMustBeLaunched | - lldb::eCommandProcessMustBePaused), + lldb::eCommandProcessMustBePaused | + lldb::eCommandProcessMustBeTraced), m_options() {} Options *GetOptions() override { return &m_options; } diff --git a/contrib/llvm-project/lldb/source/Plugins/TraceExporter/ctf/TraceExporterCTF.cpp b/contrib/llvm-project/lldb/source/Plugins/TraceExporter/ctf/TraceExporterCTF.cpp index 08bc03d78303..e98e2c83e649 100644 --- a/contrib/llvm-project/lldb/source/Plugins/TraceExporter/ctf/TraceExporterCTF.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/TraceExporter/ctf/TraceExporterCTF.cpp @@ -39,15 +39,6 @@ void TraceExporterCTF::Terminate() { PluginManager::UnregisterPlugin(CreateInstance); } -ConstString TraceExporterCTF::GetPluginNameStatic() { - static ConstString g_name("ctf"); - return g_name; -} - -ConstString TraceExporterCTF::GetPluginName() { return GetPluginNameStatic(); } - -uint32_t TraceExporterCTF::GetPluginVersion() { return 1; } - Expected<TraceExporterUP> TraceExporterCTF::CreateInstance() { return std::make_unique<TraceExporterCTF>(); } diff --git a/contrib/llvm-project/lldb/source/Plugins/TraceExporter/ctf/TraceExporterCTF.h b/contrib/llvm-project/lldb/source/Plugins/TraceExporter/ctf/TraceExporterCTF.h index 8f9e354ab0dd..74f14fc354d1 100644 --- a/contrib/llvm-project/lldb/source/Plugins/TraceExporter/ctf/TraceExporterCTF.h +++ b/contrib/llvm-project/lldb/source/Plugins/TraceExporter/ctf/TraceExporterCTF.h @@ -24,15 +24,15 @@ public: /// \{ static llvm::Expected<lldb::TraceExporterUP> CreateInstance(); - ConstString GetPluginName() override; + llvm::StringRef GetPluginName() override { + return GetPluginNameStatic(); + } static void Initialize(); static void Terminate(); - static ConstString GetPluginNameStatic(); - - uint32_t GetPluginVersion() override; + static llvm::StringRef GetPluginNameStatic() { return "ctf"; } /// \} }; diff --git a/contrib/llvm-project/lldb/source/Plugins/TraceExporter/ctf/TraceExporterCTFOptions.td b/contrib/llvm-project/lldb/source/Plugins/TraceExporter/ctf/TraceExporterCTFOptions.td index ce751f148d9f..1919e7184f9b 100644 --- a/contrib/llvm-project/lldb/source/Plugins/TraceExporter/ctf/TraceExporterCTFOptions.td +++ b/contrib/llvm-project/lldb/source/Plugins/TraceExporter/ctf/TraceExporterCTFOptions.td @@ -6,4 +6,8 @@ let Command = "thread trace export ctf" in { Arg<"ThreadIndex">, Desc<"Export the trace for the specified thread index. Otherwise, the " "currently selected thread will be used.">; + def thread_trace_export_file: Option<"file", "f">, Required, + Group<1>, + Arg<"Filename">, + Desc<"Path of the file to export the trace data">; } diff --git a/contrib/llvm-project/lldb/source/Plugins/TraceExporter/docs/htr.rst b/contrib/llvm-project/lldb/source/Plugins/TraceExporter/docs/htr.rst new file mode 100644 index 000000000000..1341cf5f0c80 --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/TraceExporter/docs/htr.rst @@ -0,0 +1,48 @@ +Hierarchical Trace Representation (HTR) +====================================== +The humongous amount of data processor traces like the ones obtained with Intel PT contain is not digestible to humans in its raw form. Given this, it is useful to summarize these massive traces by extracting useful information. Hierarchical Trace Representation (HTR) is the way lldb represents a summarized trace internally. HTR efficiently stores trace data and allows the trace data to be transformed in a way akin to compiler passes. + +Concepts +-------- +**Block:** One or more contiguous units of the trace. At minimum, the unit of a trace is the load address of an instruction. + +**Block Metadata:** Metadata associated with each *block*. For processor traces, some metadata examples are the number of instructions in the block or information on what functions are called in the block. + +**Layer:** The representation of trace data between passes. For Intel PT there are two types of layers: + + **Instruction Layer:** Composed of the load addresses of the instructions in the trace. In an effort to save space, + metadata is only stored for instructions that are of interest, not every instruction in the trace. HTR contains a + single instruction layer. + + **Block Layer:** Composed of blocks - a block in *layer n* refers to a sequence of blocks in *layer n - 1*. A block in + *layer 1* refers to a sequence of instructions in *layer 0* (the instruction layer). Metadata is stored for each block in + a block layer. HTR contains one or more block layers. + +**Pass:** A transformation applied to a *layer* that generates a new *layer* that is a more summarized, consolidated representation of the trace data. +A pass merges instructions/blocks based on its specific purpose - for example, a pass designed to summarize a processor trace by function calls would merge all the blocks of a function into a single block representing the entire function. + +The image below illusrates the transformation of a trace's representation (HTR) + +.. image:: media/htr-example.png + + +Passes +------ +A *pass* is applied to a *layer* to extract useful information (summarization) and compress the trace representation into a new *layer*. The idea is to have a series of passes where each pass specializes in extracting certain information about the trace. Some examples of potential passes include: identifying functions, identifying loops, or a more general purpose such as identifying long sequences of instructions that are repeated (i.e. Basic Super Block). Below you will find a description of each pass currently implemented in lldb. + +**Basic Super Block Reduction** + +A “basic super block” is the longest sequence of blocks that always occur in the same order. (The concept is akin to “Basic Block'' in compiler theory, but refers to dynamic occurrences rather than CFG nodes). + +The image below shows the "basic super blocks" of the sequence. Each unique "basic super block" is marked with a different color + +.. image:: media/basic_super_block_pass.png + +*Procedure to find all super blocks:* + +- For each block, compute the number of distinct predecessor and successor blocks. + + - **Predecessor** - the block that occurs directly before (to the left of) the current block + - **Successor** - the block that occurs directly after (to the right of) the current block + +- A block with more than one distinct successor is always the start of a super block, the super block will continue until the next block with more than one distinct predecessor or successor. diff --git a/contrib/llvm-project/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp b/contrib/llvm-project/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp index d4260a966857..4e60a1059363 100644 --- a/contrib/llvm-project/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp @@ -478,7 +478,7 @@ static void ParseLangArgs(LangOptions &Opts, InputKind IK, const char *triple) { LangStd = LangStandard::lang_opencl10; break; case clang::Language::OpenCLCXX: - LangStd = LangStandard::lang_openclcpp; + LangStd = LangStandard::lang_openclcpp10; break; case clang::Language::CUDA: LangStd = LangStandard::lang_cuda; @@ -570,16 +570,6 @@ TypeSystemClang::TypeSystemClang(llvm::StringRef name, // Destructor TypeSystemClang::~TypeSystemClang() { Finalize(); } -ConstString TypeSystemClang::GetPluginNameStatic() { - return ConstString("clang"); -} - -ConstString TypeSystemClang::GetPluginName() { - return TypeSystemClang::GetPluginNameStatic(); -} - -uint32_t TypeSystemClang::GetPluginVersion() { return 1; } - lldb::TypeSystemSP TypeSystemClang::CreateInstance(lldb::LanguageType language, lldb_private::Module *module, Target *target) { @@ -983,21 +973,25 @@ CompilerType TypeSystemClang::GetBuiltinTypeForDWARFEncodingAndBitSize( } break; - case DW_ATE_complex_float: - if (QualTypeMatchesBitSize(bit_size, ast, ast.FloatComplexTy)) - return GetType(ast.FloatComplexTy); - else if (QualTypeMatchesBitSize(bit_size, ast, ast.DoubleComplexTy)) - return GetType(ast.DoubleComplexTy); - else if (QualTypeMatchesBitSize(bit_size, ast, ast.LongDoubleComplexTy)) - return GetType(ast.LongDoubleComplexTy); - else { - CompilerType complex_float_clang_type = - GetBuiltinTypeForDWARFEncodingAndBitSize("float", DW_ATE_float, - bit_size / 2); - return GetType( - ast.getComplexType(ClangUtil::GetQualType(complex_float_clang_type))); - } - break; + case DW_ATE_complex_float: { + CanQualType FloatComplexTy = ast.getComplexType(ast.FloatTy); + if (QualTypeMatchesBitSize(bit_size, ast, FloatComplexTy)) + return GetType(FloatComplexTy); + + CanQualType DoubleComplexTy = ast.getComplexType(ast.DoubleTy); + if (QualTypeMatchesBitSize(bit_size, ast, DoubleComplexTy)) + return GetType(DoubleComplexTy); + + CanQualType LongDoubleComplexTy = ast.getComplexType(ast.LongDoubleTy); + if (QualTypeMatchesBitSize(bit_size, ast, LongDoubleComplexTy)) + return GetType(LongDoubleComplexTy); + + CompilerType complex_float_clang_type = + GetBuiltinTypeForDWARFEncodingAndBitSize("float", DW_ATE_float, + bit_size / 2); + return GetType( + ast.getComplexType(ClangUtil::GetQualType(complex_float_clang_type))); + } case DW_ATE_float: if (type_name == "float" && @@ -1153,20 +1147,12 @@ CompilerType TypeSystemClang::GetBuiltinTypeForDWARFEncodingAndBitSize( } break; } - // This assert should fire for anything that we don't catch above so we know - // to fix any issues we run into. - if (!type_name.empty()) { - std::string type_name_str = type_name.str(); - Host::SystemLog(Host::eSystemLogError, - "error: need to add support for DW_TAG_base_type '%s' " - "encoded with DW_ATE = 0x%x, bit_size = %u\n", - type_name_str.c_str(), dw_ate, bit_size); - } else { - Host::SystemLog(Host::eSystemLogError, "error: need to add support for " - "DW_TAG_base_type encoded with " - "DW_ATE = 0x%x, bit_size = %u\n", - dw_ate, bit_size); - } + + Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_TYPES); + LLDB_LOG(log, + "error: need to add support for DW_TAG_base_type '{0}' " + "encoded with DW_ATE = {1:x}, bit_size = {2}", + type_name, dw_ate, bit_size); return CompilerType(); } @@ -1341,19 +1327,16 @@ CompilerType TypeSystemClang::CreateRecordType( decl->setAnonymousStructOrUnion(true); } - if (decl) { - if (metadata) - SetMetadata(decl, *metadata); + if (metadata) + SetMetadata(decl, *metadata); - if (access_type != eAccessNone) - decl->setAccess(ConvertAccessTypeToAccessSpecifier(access_type)); + if (access_type != eAccessNone) + decl->setAccess(ConvertAccessTypeToAccessSpecifier(access_type)); - if (decl_ctx) - decl_ctx->addDecl(decl); + if (decl_ctx) + decl_ctx->addDecl(decl); - return GetType(ast.getTagDeclType(decl)); - } - return CompilerType(); + return GetType(ast.getTagDeclType(decl)); } namespace { @@ -1560,7 +1543,7 @@ static bool ClassTemplateAllowsToInstantiationArgs( ClassTemplateDecl *TypeSystemClang::CreateClassTemplateDecl( DeclContext *decl_ctx, OptionalClangModuleID owning_module, - lldb::AccessType access_type, const char *class_name, int kind, + lldb::AccessType access_type, llvm::StringRef class_name, int kind, const TemplateParameterInfos &template_param_infos) { ASTContext &ast = getASTContext(); @@ -1619,15 +1602,13 @@ ClassTemplateDecl *TypeSystemClang::CreateClassTemplateDecl( template_cxx_decl->setDescribedClassTemplate(class_template_decl); SetOwningModule(class_template_decl, owning_module); - if (class_template_decl) { - if (access_type != eAccessNone) - class_template_decl->setAccess( - ConvertAccessTypeToAccessSpecifier(access_type)); + if (access_type != eAccessNone) + class_template_decl->setAccess( + ConvertAccessTypeToAccessSpecifier(access_type)); - decl_ctx->addDecl(class_template_decl); + decl_ctx->addDecl(class_template_decl); - VerifyDecl(class_template_decl); - } + VerifyDecl(class_template_decl); return class_template_decl; } @@ -1817,7 +1798,7 @@ CompilerType TypeSystemClang::CreateObjCClass( decl->setImplicit(isInternal); SetOwningModule(decl, owning_module); - if (decl && metadata) + if (metadata) SetMetadata(decl, *metadata); return GetType(ast.getObjCInterfaceType(decl)); @@ -2053,11 +2034,11 @@ TypeSystemClang::GetOpaqueCompilerType(clang::ASTContext *ast, case eBasicTypeLongDouble: return ast->LongDoubleTy.getAsOpaquePtr(); case eBasicTypeFloatComplex: - return ast->FloatComplexTy.getAsOpaquePtr(); + return ast->getComplexType(ast->FloatTy).getAsOpaquePtr(); case eBasicTypeDoubleComplex: - return ast->DoubleComplexTy.getAsOpaquePtr(); + return ast->getComplexType(ast->DoubleTy).getAsOpaquePtr(); case eBasicTypeLongDoubleComplex: - return ast->LongDoubleComplexTy.getAsOpaquePtr(); + return ast->getComplexType(ast->LongDoubleTy).getAsOpaquePtr(); case eBasicTypeObjCID: return ast->getObjCIdType().getAsOpaquePtr(); case eBasicTypeObjCClass: @@ -2155,8 +2136,7 @@ FunctionDecl *TypeSystemClang::CreateFunctionDeclaration( ? ConstexprSpecKind::Constexpr : ConstexprSpecKind::Unspecified); SetOwningModule(func_decl, owning_module); - if (func_decl) - decl_ctx->addDecl(func_decl); + decl_ctx->addDecl(func_decl); VerifyDecl(func_decl); @@ -2302,7 +2282,7 @@ CompilerType TypeSystemClang::GetOrCreateStructForIdentifier( #pragma mark Enumeration Types CompilerType TypeSystemClang::CreateEnumerationType( - const char *name, clang::DeclContext *decl_ctx, + llvm::StringRef name, clang::DeclContext *decl_ctx, OptionalClangModuleID owning_module, const Declaration &decl, const CompilerType &integer_clang_type, bool is_scoped) { // TODO: Do something intelligent with the Declaration object passed in @@ -2313,24 +2293,21 @@ CompilerType TypeSystemClang::CreateEnumerationType( // const bool IsFixed = false; EnumDecl *enum_decl = EnumDecl::CreateDeserialized(ast, 0); enum_decl->setDeclContext(decl_ctx); - if (name && name[0]) + if (!name.empty()) enum_decl->setDeclName(&ast.Idents.get(name)); enum_decl->setScoped(is_scoped); enum_decl->setScopedUsingClassTag(is_scoped); enum_decl->setFixed(false); SetOwningModule(enum_decl, owning_module); - if (enum_decl) { - if (decl_ctx) - decl_ctx->addDecl(enum_decl); + if (decl_ctx) + decl_ctx->addDecl(enum_decl); - // TODO: check if we should be setting the promotion type too? - enum_decl->setIntegerType(ClangUtil::GetQualType(integer_clang_type)); + // TODO: check if we should be setting the promotion type too? + enum_decl->setIntegerType(ClangUtil::GetQualType(integer_clang_type)); - enum_decl->setAccess(AS_public); // TODO respect what's in the debug info + enum_decl->setAccess(AS_public); // TODO respect what's in the debug info - return GetType(ast.getTagDeclType(enum_decl)); - } - return CompilerType(); + return GetType(ast.getTagDeclType(enum_decl)); } CompilerType TypeSystemClang::GetIntTypeFromBitSize(size_t bit_size, @@ -2950,7 +2927,12 @@ bool TypeSystemClang::IsCharType(lldb::opaque_compiler_type_t type) { } bool TypeSystemClang::IsCompleteType(lldb::opaque_compiler_type_t type) { - const bool allow_completion = false; + // If the type hasn't been lazily completed yet, complete it now so that we + // can give the caller an accurate answer whether the type actually has a + // definition. Without completing the type now we would just tell the user + // the current (internal) completeness state of the type and most users don't + // care (or even know) about this behavior. + const bool allow_completion = true; return GetCompleteQualType(&getASTContext(), GetQualType(type), allow_completion); } @@ -4248,7 +4230,13 @@ static clang::QualType GetFullyUnqualifiedType_Impl(clang::ASTContext *ast, if (qual_type->isPointerType()) qual_type = ast->getPointerType( GetFullyUnqualifiedType_Impl(ast, qual_type->getPointeeType())); - else + else if (const ConstantArrayType *arr = + ast->getAsConstantArrayType(qual_type)) { + qual_type = ast->getConstantArrayType( + GetFullyUnqualifiedType_Impl(ast, arr->getElementType()), + arr->getSize(), arr->getSizeExpr(), arr->getSizeModifier(), + arr->getIndexTypeQualifiers().getAsOpaqueValue()); + } else qual_type = qual_type.getUnqualifiedType(); qual_type.removeLocalConst(); qual_type.removeLocalRestrict(); @@ -4824,6 +4812,7 @@ lldb::Encoding TypeSystemClang::GetEncoding(lldb::opaque_compiler_type_t type, case clang::BuiltinType::Double: case clang::BuiltinType::LongDouble: case clang::BuiltinType::BFloat16: + case clang::BuiltinType::Ibm128: return lldb::eEncodingIEEE754; case clang::BuiltinType::ObjCClass: @@ -6503,7 +6492,8 @@ CompilerType TypeSystemClang::GetChildCompilerTypeAtIndex( case clang::Type::RValueReference: if (idx_is_valid) { const clang::ReferenceType *reference_type = - llvm::cast<clang::ReferenceType>(GetQualType(type).getTypePtr()); + llvm::cast<clang::ReferenceType>( + RemoveWrappingTypes(GetQualType(type)).getTypePtr()); CompilerType pointee_clang_type = GetType(reference_type->getPointeeType()); if (transparent_pointers && pointee_clang_type.IsAggregateType()) { @@ -8367,9 +8357,8 @@ TypeSystemClang::dump(lldb::opaque_compiler_type_t type) const { } #endif -void TypeSystemClang::Dump(Stream &s) { - Decl *tu = Decl::castFromDeclContext(GetTranslationUnitDecl()); - tu->dump(s.AsRawOstream()); +void TypeSystemClang::Dump(llvm::raw_ostream &output) { + GetTranslationUnitDecl()->dump(output); } void TypeSystemClang::DumpFromSymbolFile(Stream &s, @@ -9759,6 +9748,41 @@ ScratchTypeSystemClang::GetForTarget(Target &target, return &scratch_ast.GetIsolatedAST(*ast_kind); } +/// Returns a human-readable name that uniquely identifiers the sub-AST kind. +static llvm::StringRef +GetNameForIsolatedASTKind(ScratchTypeSystemClang::IsolatedASTKind kind) { + switch (kind) { + case ScratchTypeSystemClang::IsolatedASTKind::CppModules: + return "C++ modules"; + } + llvm_unreachable("Unimplemented IsolatedASTKind?"); +} + +void ScratchTypeSystemClang::Dump(llvm::raw_ostream &output) { + // First dump the main scratch AST. + output << "State of scratch Clang type system:\n"; + TypeSystemClang::Dump(output); + + // Now sort the isolated sub-ASTs. + typedef std::pair<IsolatedASTKey, TypeSystem *> KeyAndTS; + std::vector<KeyAndTS> sorted_typesystems; + for (const auto &a : m_isolated_asts) + sorted_typesystems.emplace_back(a.first, a.second.get()); + llvm::stable_sort(sorted_typesystems, + [](const KeyAndTS &lhs, const KeyAndTS &rhs) { + return lhs.first < rhs.first; + }); + + // Dump each sub-AST too. + for (const auto &a : sorted_typesystems) { + IsolatedASTKind kind = + static_cast<ScratchTypeSystemClang::IsolatedASTKind>(a.first); + output << "State of scratch Clang type subsystem " + << GetNameForIsolatedASTKind(kind) << ":\n"; + a.second->Dump(output); + } +} + UserExpression *ScratchTypeSystemClang::GetUserExpression( llvm::StringRef expr, llvm::StringRef prefix, lldb::LanguageType language, Expression::ResultType desired_type, diff --git a/contrib/llvm-project/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h b/contrib/llvm-project/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h index 4a6891795bd8..5e75a8aba9e8 100644 --- a/contrib/llvm-project/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h +++ b/contrib/llvm-project/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h @@ -138,11 +138,9 @@ public: void Finalize() override; // PluginInterface functions - ConstString GetPluginName() override; + llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); } - uint32_t GetPluginVersion() override; - - static ConstString GetPluginNameStatic(); + static llvm::StringRef GetPluginNameStatic() { return "clang"; } static lldb::TypeSystemSP CreateInstance(lldb::LanguageType language, Module *module, Target *target); @@ -345,11 +343,10 @@ public: clang::FunctionDecl *func_decl, clang::FunctionTemplateDecl *Template, const TemplateParameterInfos &infos); - clang::ClassTemplateDecl * - CreateClassTemplateDecl(clang::DeclContext *decl_ctx, - OptionalClangModuleID owning_module, - lldb::AccessType access_type, const char *class_name, - int kind, const TemplateParameterInfos &infos); + clang::ClassTemplateDecl *CreateClassTemplateDecl( + clang::DeclContext *decl_ctx, OptionalClangModuleID owning_module, + lldb::AccessType access_type, llvm::StringRef class_name, int kind, + const TemplateParameterInfos &infos); clang::TemplateTemplateParmDecl * CreateTemplateTemplateParmDecl(const char *template_name); @@ -400,14 +397,7 @@ public: CompilerType CreateFunctionType(const CompilerType &result_type, const CompilerType *args, unsigned num_args, bool is_variadic, unsigned type_quals, - clang::CallingConv cc); - - CompilerType CreateFunctionType(const CompilerType &result_type, - const CompilerType *args, unsigned num_args, - bool is_variadic, unsigned type_quals) { - return CreateFunctionType(result_type, args, num_args, is_variadic, - type_quals, clang::CC_C); - } + clang::CallingConv cc = clang::CC_C); clang::ParmVarDecl * CreateParameterDeclaration(clang::DeclContext *decl_ctx, @@ -426,7 +416,7 @@ public: size_t element_count, bool is_vector); // Enumeration Types - CompilerType CreateEnumerationType(const char *name, + CompilerType CreateEnumerationType(llvm::StringRef name, clang::DeclContext *decl_ctx, OptionalClangModuleID owning_module, const Declaration &decl, @@ -947,7 +937,8 @@ public: LLVM_DUMP_METHOD void dump(lldb::opaque_compiler_type_t type) const override; #endif - void Dump(Stream &s); + /// \see lldb_private::TypeSystem::Dump + void Dump(llvm::raw_ostream &output) override; /// Dump clang AST types from the symbol file. /// @@ -1173,6 +1164,9 @@ public: return GetForTarget(target, InferIsolatedASTKindFromLangOpts(lang_opts)); } + /// \see lldb_private::TypeSystem::Dump + void Dump(llvm::raw_ostream &output) override; + UserExpression * GetUserExpression(llvm::StringRef expr, llvm::StringRef prefix, lldb::LanguageType language, diff --git a/contrib/llvm-project/lldb/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.cpp b/contrib/llvm-project/lldb/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.cpp index 65947c5f833b..ccaac687ed7a 100644 --- a/contrib/llvm-project/lldb/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.cpp @@ -333,13 +333,6 @@ UnwindAssemblyInstEmulation::CreateInstance(const ArchSpec &arch) { return nullptr; } -// PluginInterface protocol in UnwindAssemblyParser_x86 -ConstString UnwindAssemblyInstEmulation::GetPluginName() { - return GetPluginNameStatic(); -} - -uint32_t UnwindAssemblyInstEmulation::GetPluginVersion() { return 1; } - void UnwindAssemblyInstEmulation::Initialize() { PluginManager::RegisterPlugin(GetPluginNameStatic(), GetPluginDescriptionStatic(), CreateInstance); @@ -349,12 +342,7 @@ void UnwindAssemblyInstEmulation::Terminate() { PluginManager::UnregisterPlugin(CreateInstance); } -ConstString UnwindAssemblyInstEmulation::GetPluginNameStatic() { - static ConstString g_name("inst-emulation"); - return g_name; -} - -const char *UnwindAssemblyInstEmulation::GetPluginDescriptionStatic() { +llvm::StringRef UnwindAssemblyInstEmulation::GetPluginDescriptionStatic() { return "Instruction emulation based unwind information."; } diff --git a/contrib/llvm-project/lldb/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.h b/contrib/llvm-project/lldb/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.h index 5784a42a8269..97cb04e51408 100644 --- a/contrib/llvm-project/lldb/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.h +++ b/contrib/llvm-project/lldb/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.h @@ -52,13 +52,11 @@ public: static void Terminate(); - static lldb_private::ConstString GetPluginNameStatic(); + static llvm::StringRef GetPluginNameStatic() { return "inst-emulation"; } - static const char *GetPluginDescriptionStatic(); + static llvm::StringRef GetPluginDescriptionStatic(); - lldb_private::ConstString GetPluginName() override; - - uint32_t GetPluginVersion() override; + llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); } private: // Call CreateInstance to get an instance of this class diff --git a/contrib/llvm-project/lldb/source/Plugins/UnwindAssembly/x86/UnwindAssembly-x86.cpp b/contrib/llvm-project/lldb/source/Plugins/UnwindAssembly/x86/UnwindAssembly-x86.cpp index 402a70cd025f..eca78a9b3a04 100644 --- a/contrib/llvm-project/lldb/source/Plugins/UnwindAssembly/x86/UnwindAssembly-x86.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/UnwindAssembly/x86/UnwindAssembly-x86.cpp @@ -239,14 +239,6 @@ UnwindAssembly *UnwindAssembly_x86::CreateInstance(const ArchSpec &arch) { return nullptr; } -// PluginInterface protocol in UnwindAssemblyParser_x86 - -ConstString UnwindAssembly_x86::GetPluginName() { - return GetPluginNameStatic(); -} - -uint32_t UnwindAssembly_x86::GetPluginVersion() { return 1; } - void UnwindAssembly_x86::Initialize() { PluginManager::RegisterPlugin(GetPluginNameStatic(), GetPluginDescriptionStatic(), CreateInstance); @@ -256,11 +248,6 @@ void UnwindAssembly_x86::Terminate() { PluginManager::UnregisterPlugin(CreateInstance); } -lldb_private::ConstString UnwindAssembly_x86::GetPluginNameStatic() { - static ConstString g_name("x86"); - return g_name; -} - -const char *UnwindAssembly_x86::GetPluginDescriptionStatic() { +llvm::StringRef UnwindAssembly_x86::GetPluginDescriptionStatic() { return "i386 and x86_64 assembly language profiler plugin."; } diff --git a/contrib/llvm-project/lldb/source/Plugins/UnwindAssembly/x86/UnwindAssembly-x86.h b/contrib/llvm-project/lldb/source/Plugins/UnwindAssembly/x86/UnwindAssembly-x86.h index 3e1588f2065c..3857c8776b02 100644 --- a/contrib/llvm-project/lldb/source/Plugins/UnwindAssembly/x86/UnwindAssembly-x86.h +++ b/contrib/llvm-project/lldb/source/Plugins/UnwindAssembly/x86/UnwindAssembly-x86.h @@ -46,13 +46,11 @@ public: static void Terminate(); - static lldb_private::ConstString GetPluginNameStatic(); + static llvm::StringRef GetPluginNameStatic() { return "x86"; } - static const char *GetPluginDescriptionStatic(); + static llvm::StringRef GetPluginDescriptionStatic(); - lldb_private::ConstString GetPluginName() override; - - uint32_t GetPluginVersion() override; + llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); } private: UnwindAssembly_x86(const lldb_private::ArchSpec &arch); diff --git a/contrib/llvm-project/lldb/source/Symbol/Block.cpp b/contrib/llvm-project/lldb/source/Symbol/Block.cpp index fc246ac8575d..4aafef34bd2d 100644 --- a/contrib/llvm-project/lldb/source/Symbol/Block.cpp +++ b/contrib/llvm-project/lldb/source/Symbol/Block.cpp @@ -122,6 +122,16 @@ Block *Block::FindBlockByID(user_id_t block_id) { return matching_block; } +Block *Block::FindInnermostBlockByOffset(const lldb::addr_t offset) { + if (!Contains(offset)) + return nullptr; + for (const BlockSP &block_sp : m_children) { + if (Block *block = block_sp->FindInnermostBlockByOffset(offset)) + return block; + } + return this; +} + void Block::CalculateSymbolContext(SymbolContext *sc) { if (m_parent_scope) m_parent_scope->CalculateSymbolContext(sc); diff --git a/contrib/llvm-project/lldb/source/Symbol/CompileUnit.cpp b/contrib/llvm-project/lldb/source/Symbol/CompileUnit.cpp index 588ed4976d65..7c840d8bb064 100644 --- a/contrib/llvm-project/lldb/source/Symbol/CompileUnit.cpp +++ b/contrib/llvm-project/lldb/source/Symbol/CompileUnit.cpp @@ -52,7 +52,7 @@ void CompileUnit::DumpSymbolContext(Stream *s) { void CompileUnit::GetDescription(Stream *s, lldb::DescriptionLevel level) const { - const char *language = Language::GetNameForLanguageType(m_language); + const char *language = GetCachedLanguage(); *s << "id = " << (const UserID &)*this << ", file = \"" << this->GetPrimaryFile() << "\", language = \"" << language << '"'; } @@ -97,12 +97,18 @@ lldb::FunctionSP CompileUnit::FindFunction( return {}; } +const char *CompileUnit::GetCachedLanguage() const { + if (m_flags.IsClear(flagsParsedLanguage)) + return "<not loaded>"; + return Language::GetNameForLanguageType(m_language); +} + // Dump the current contents of this object. No functions that cause on demand // parsing of functions, globals, statics are called, so this is a good // function to call to get an idea of the current contents of the CompileUnit // object. void CompileUnit::Dump(Stream *s, bool show_context) const { - const char *language = Language::GetNameForLanguageType(m_language); + const char *language = GetCachedLanguage(); s->Printf("%p: ", static_cast<const void *>(this)); s->Indent(); @@ -175,6 +181,10 @@ void CompileUnit::SetSupportFiles(const FileSpecList &support_files) { m_support_files = support_files; } +void CompileUnit::SetSupportFiles(FileSpecList &&support_files) { + m_support_files = std::move(support_files); +} + DebugMacros *CompileUnit::GetDebugMacros() { if (m_debug_macros_sp.get() == nullptr) { if (m_flags.IsClear(flagsParsedDebugMacros)) { @@ -309,8 +319,13 @@ void CompileUnit::ResolveSymbolContext( // subsequent line exact matches below. const bool inlines = false; const bool exact = true; - SourceLocationSpec found_entry(line_entry.file, line_entry.line, - line_entry.column, inlines, exact); + const llvm::Optional<uint16_t> column = + src_location_spec.GetColumn().hasValue() + ? llvm::Optional<uint16_t>(line_entry.column) + : llvm::None; + + SourceLocationSpec found_entry(line_entry.file, line_entry.line, column, + inlines, exact); while (line_idx != UINT32_MAX) { // If they only asked for the line entry, then we're done, we can diff --git a/contrib/llvm-project/lldb/source/Symbol/DeclVendor.cpp b/contrib/llvm-project/lldb/source/Symbol/DeclVendor.cpp index cf87f4f879b1..e99ebfee4cff 100644 --- a/contrib/llvm-project/lldb/source/Symbol/DeclVendor.cpp +++ b/contrib/llvm-project/lldb/source/Symbol/DeclVendor.cpp @@ -17,8 +17,6 @@ using namespace lldb_private; std::vector<CompilerType> DeclVendor::FindTypes(ConstString name, uint32_t max_matches) { - // FIXME: This depends on clang, but should be able to support any - // TypeSystem. std::vector<CompilerType> ret; std::vector<CompilerDecl> decls; if (FindDecls(name, /*append*/ true, max_matches, decls)) diff --git a/contrib/llvm-project/lldb/source/Symbol/LocateSymbolFileMacOSX.cpp b/contrib/llvm-project/lldb/source/Symbol/LocateSymbolFileMacOSX.cpp index 2655e4de9063..a13b4a7a54f2 100644 --- a/contrib/llvm-project/lldb/source/Symbol/LocateSymbolFileMacOSX.cpp +++ b/contrib/llvm-project/lldb/source/Symbol/LocateSymbolFileMacOSX.cpp @@ -414,9 +414,8 @@ static bool GetModuleSpecInfoFromUUIDDictionary(CFDictionaryRef uuid_dict, // last two filename parts from the source remapping and get a more // general source remapping that still works. Add this as another // option in addition to the full source path remap. - module_spec.GetSourceMappingList().Append( - ConstString(DBGBuildSourcePath.c_str()), - ConstString(DBGSourcePath.c_str()), true); + module_spec.GetSourceMappingList().Append(DBGBuildSourcePath, + DBGSourcePath, true); if (do_truncate_remapping_names) { FileSpec build_path(DBGBuildSourcePath.c_str()); FileSpec source_path(DBGSourcePath.c_str()); @@ -425,8 +424,7 @@ static bool GetModuleSpecInfoFromUUIDDictionary(CFDictionaryRef uuid_dict, source_path.RemoveLastPathComponent(); source_path.RemoveLastPathComponent(); module_spec.GetSourceMappingList().Append( - ConstString(build_path.GetPath().c_str()), - ConstString(source_path.GetPath().c_str()), true); + build_path.GetPath(), source_path.GetPath(), true); } } } @@ -458,9 +456,8 @@ static bool GetModuleSpecInfoFromUUIDDictionary(CFDictionaryRef uuid_dict, FileSystem::Instance().Resolve(resolved_source_path); DBGSourcePath = resolved_source_path.GetPath(); } - module_spec.GetSourceMappingList().Append( - ConstString(DBGBuildSourcePath.c_str()), - ConstString(DBGSourcePath.c_str()), true); + module_spec.GetSourceMappingList().Append(DBGBuildSourcePath, + DBGSourcePath, true); } } return success; diff --git a/contrib/llvm-project/lldb/source/Symbol/Symbol.cpp b/contrib/llvm-project/lldb/source/Symbol/Symbol.cpp index 251f9104ad54..a8c81ee3082f 100644 --- a/contrib/llvm-project/lldb/source/Symbol/Symbol.cpp +++ b/contrib/llvm-project/lldb/source/Symbol/Symbol.cpp @@ -115,7 +115,8 @@ void Symbol::Clear() { } bool Symbol::ValueIsAddress() const { - return m_addr_range.GetBaseAddress().GetSection().get() != nullptr; + return m_addr_range.GetBaseAddress().GetSection().get() != nullptr || + m_type == eSymbolTypeAbsolute; } ConstString Symbol::GetDisplayName() const { diff --git a/contrib/llvm-project/lldb/source/Symbol/SymbolContext.cpp b/contrib/llvm-project/lldb/source/Symbol/SymbolContext.cpp index 2e8fe1cec30e..f1c3a9e5b4e0 100644 --- a/contrib/llvm-project/lldb/source/Symbol/SymbolContext.cpp +++ b/contrib/llvm-project/lldb/source/Symbol/SymbolContext.cpp @@ -11,7 +11,6 @@ #include "lldb/Core/Module.h" #include "lldb/Core/ModuleSpec.h" #include "lldb/Host/Host.h" -#include "lldb/Host/StringConvert.h" #include "lldb/Symbol/Block.h" #include "lldb/Symbol/CompileUnit.h" #include "lldb/Symbol/ObjectFile.h" @@ -977,13 +976,11 @@ bool SymbolContextSpecifier::AddSpecification(const char *spec_string, m_type |= eFileSpecified; break; case eLineStartSpecified: - m_start_line = StringConvert::ToSInt32(spec_string, 0, 0, &return_value); - if (return_value) + if ((return_value = llvm::to_integer(spec_string, m_start_line))) m_type |= eLineStartSpecified; break; case eLineEndSpecified: - m_end_line = StringConvert::ToSInt32(spec_string, 0, 0, &return_value); - if (return_value) + if ((return_value = llvm::to_integer(spec_string, m_end_line))) m_type |= eLineEndSpecified; break; case eFunctionSpecified: diff --git a/contrib/llvm-project/lldb/source/Symbol/SymbolFile.cpp b/contrib/llvm-project/lldb/source/Symbol/SymbolFile.cpp index 152bbe8de6cb..53f8dd68c8b7 100644 --- a/contrib/llvm-project/lldb/source/Symbol/SymbolFile.cpp +++ b/contrib/llvm-project/lldb/source/Symbol/SymbolFile.cpp @@ -236,3 +236,15 @@ void SymbolFile::Dump(Stream &s) { } SymbolFile::RegisterInfoResolver::~RegisterInfoResolver() = default; + +uint64_t SymbolFile::GetDebugInfoSize() { + if (!m_objfile_sp) + return 0; + ModuleSP module_sp(m_objfile_sp->GetModule()); + if (!module_sp) + return 0; + const SectionList *section_list = module_sp->GetSectionList(); + if (section_list) + return section_list->GetDebugInfoSize(); + return 0; +} diff --git a/contrib/llvm-project/lldb/source/Symbol/SymbolVendor.cpp b/contrib/llvm-project/lldb/source/Symbol/SymbolVendor.cpp index 0ef332a5813f..d26363130e2d 100644 --- a/contrib/llvm-project/lldb/source/Symbol/SymbolVendor.cpp +++ b/contrib/llvm-project/lldb/source/Symbol/SymbolVendor.cpp @@ -69,11 +69,3 @@ void SymbolVendor::AddSymbolFileRepresentation(const ObjectFileSP &objfile_sp) { m_sym_file_up.reset(SymbolFile::FindPlugin(objfile_sp)); } } - -// PluginInterface protocol -lldb_private::ConstString SymbolVendor::GetPluginName() { - static ConstString g_name("vendor-default"); - return g_name; -} - -uint32_t SymbolVendor::GetPluginVersion() { return 1; } diff --git a/contrib/llvm-project/lldb/source/Symbol/Symtab.cpp b/contrib/llvm-project/lldb/source/Symbol/Symtab.cpp index 313b451601ae..19c1fee2bb38 100644 --- a/contrib/llvm-project/lldb/source/Symbol/Symtab.cpp +++ b/contrib/llvm-project/lldb/source/Symbol/Symtab.cpp @@ -248,10 +248,8 @@ static bool lldb_skip_name(llvm::StringRef mangled, // No filters for this scheme yet. Include all names in indexing. case Mangled::eManglingSchemeMSVC: - return false; - - // No filters for this scheme yet. Include all names in indexing. case Mangled::eManglingSchemeRustV0: + case Mangled::eManglingSchemeD: return false; // Don't try and demangle things we can't categorize. @@ -265,6 +263,7 @@ void Symtab::InitNameIndexes() { // Protected function, no need to lock mutex... if (!m_name_indexes_computed) { m_name_indexes_computed = true; + ElapsedTime elapsed(m_objfile->GetModule()->GetSymtabIndexTime()); LLDB_SCOPED_TIMER(); // Collect all loaded language plugins. @@ -1099,6 +1098,7 @@ void Symtab::FindFunctionSymbols(ConstString name, uint32_t name_type_mask, case eSymbolTypeCode: case eSymbolTypeResolver: case eSymbolTypeReExported: + case eSymbolTypeAbsolute: symbol_indexes.push_back(temp_symbol_indexes[i]); break; default: diff --git a/contrib/llvm-project/lldb/source/Symbol/UnwindPlan.cpp b/contrib/llvm-project/lldb/source/Symbol/UnwindPlan.cpp index 41bd8cd46ad8..5547998691db 100644 --- a/contrib/llvm-project/lldb/source/Symbol/UnwindPlan.cpp +++ b/contrib/llvm-project/lldb/source/Symbol/UnwindPlan.cpp @@ -8,7 +8,6 @@ #include "lldb/Symbol/UnwindPlan.h" -#include "lldb/Expression/DWARFExpression.h" #include "lldb/Target/Process.h" #include "lldb/Target/RegisterContext.h" #include "lldb/Target/Target.h" diff --git a/contrib/llvm-project/lldb/source/Target/ABI.cpp b/contrib/llvm-project/lldb/source/Target/ABI.cpp index c3342caf8742..6e8772cbd142 100644 --- a/contrib/llvm-project/lldb/source/Target/ABI.cpp +++ b/contrib/llvm-project/lldb/source/Target/ABI.cpp @@ -16,7 +16,7 @@ #include "lldb/Target/Target.h" #include "lldb/Target/Thread.h" #include "lldb/Utility/Log.h" -#include "llvm/Support/TargetRegistry.h" +#include "llvm/MC/TargetRegistry.h" #include <cctype> using namespace lldb; @@ -214,33 +214,39 @@ std::unique_ptr<llvm::MCRegisterInfo> ABI::MakeMCRegisterInfo(const ArchSpec &ar return info_up; } -void RegInfoBasedABI::AugmentRegisterInfo(RegisterInfo &info) { - if (info.kinds[eRegisterKindEHFrame] != LLDB_INVALID_REGNUM && - info.kinds[eRegisterKindDWARF] != LLDB_INVALID_REGNUM) - return; - - RegisterInfo abi_info; - if (!GetRegisterInfoByName(info.name, abi_info)) - return; - - if (info.kinds[eRegisterKindEHFrame] == LLDB_INVALID_REGNUM) - info.kinds[eRegisterKindEHFrame] = abi_info.kinds[eRegisterKindEHFrame]; - if (info.kinds[eRegisterKindDWARF] == LLDB_INVALID_REGNUM) - info.kinds[eRegisterKindDWARF] = abi_info.kinds[eRegisterKindDWARF]; - if (info.kinds[eRegisterKindGeneric] == LLDB_INVALID_REGNUM) - info.kinds[eRegisterKindGeneric] = abi_info.kinds[eRegisterKindGeneric]; +void RegInfoBasedABI::AugmentRegisterInfo( + std::vector<DynamicRegisterInfo::Register> ®s) { + for (DynamicRegisterInfo::Register &info : regs) { + if (info.regnum_ehframe != LLDB_INVALID_REGNUM && + info.regnum_dwarf != LLDB_INVALID_REGNUM) + continue; + + RegisterInfo abi_info; + if (!GetRegisterInfoByName(info.name.GetStringRef(), abi_info)) + continue; + + if (info.regnum_ehframe == LLDB_INVALID_REGNUM) + info.regnum_ehframe = abi_info.kinds[eRegisterKindEHFrame]; + if (info.regnum_dwarf == LLDB_INVALID_REGNUM) + info.regnum_dwarf = abi_info.kinds[eRegisterKindDWARF]; + if (info.regnum_generic == LLDB_INVALID_REGNUM) + info.regnum_generic = abi_info.kinds[eRegisterKindGeneric]; + } } -void MCBasedABI::AugmentRegisterInfo(RegisterInfo &info) { - uint32_t eh, dwarf; - std::tie(eh, dwarf) = GetEHAndDWARFNums(info.name); - - if (info.kinds[eRegisterKindEHFrame] == LLDB_INVALID_REGNUM) - info.kinds[eRegisterKindEHFrame] = eh; - if (info.kinds[eRegisterKindDWARF] == LLDB_INVALID_REGNUM) - info.kinds[eRegisterKindDWARF] = dwarf; - if (info.kinds[eRegisterKindGeneric] == LLDB_INVALID_REGNUM) - info.kinds[eRegisterKindGeneric] = GetGenericNum(info.name); +void MCBasedABI::AugmentRegisterInfo( + std::vector<DynamicRegisterInfo::Register> ®s) { + for (DynamicRegisterInfo::Register &info : regs) { + uint32_t eh, dwarf; + std::tie(eh, dwarf) = GetEHAndDWARFNums(info.name.GetStringRef()); + + if (info.regnum_ehframe == LLDB_INVALID_REGNUM) + info.regnum_ehframe = eh; + if (info.regnum_dwarf == LLDB_INVALID_REGNUM) + info.regnum_dwarf = dwarf; + if (info.regnum_generic == LLDB_INVALID_REGNUM) + info.regnum_generic = GetGenericNum(info.name.GetStringRef()); + } } std::pair<uint32_t, uint32_t> diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.cpp b/contrib/llvm-project/lldb/source/Target/DynamicRegisterInfo.cpp index a85d7bd6f525..9f894f86aea8 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.cpp +++ b/contrib/llvm-project/lldb/source/Target/DynamicRegisterInfo.cpp @@ -6,13 +6,12 @@ // //===----------------------------------------------------------------------===// -#include "DynamicRegisterInfo.h" - +#include "lldb/Target/DynamicRegisterInfo.h" #include "lldb/Core/StreamFile.h" #include "lldb/DataFormatters/FormatManager.h" -#include "lldb/Host/StringConvert.h" #include "lldb/Interpreter/OptionArgParser.h" #include "lldb/Utility/ArchSpec.h" +#include "lldb/Utility/Log.h" #include "lldb/Utility/RegularExpression.h" #include "lldb/Utility/StringExtractor.h" #include "lldb/Utility/StructuredData.h" @@ -43,7 +42,6 @@ void DynamicRegisterInfo::MoveFrom(DynamicRegisterInfo &&info) { m_set_names = std::move(info.m_set_names); m_value_regs_map = std::move(info.m_value_regs_map); m_invalidate_regs_map = std::move(info.m_invalidate_regs_map); - m_dynamic_reg_size_map = std::move(info.m_dynamic_reg_size_map); m_reg_data_byte_size = info.m_reg_data_byte_size; m_finalized = info.m_finalized; @@ -57,9 +55,144 @@ void DynamicRegisterInfo::MoveFrom(DynamicRegisterInfo &&info) { info.Clear(); } +llvm::Expected<uint32_t> DynamicRegisterInfo::ByteOffsetFromSlice( + uint32_t index, llvm::StringRef slice_str, lldb::ByteOrder byte_order) { + // 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 llvm::Regex g_bitfield_regex( + "([A-Za-z_][A-Za-z0-9_]*)\\[([0-9]+):([0-9]+)\\]"); + llvm::SmallVector<llvm::StringRef, 4> matches; + if (!g_bitfield_regex.match(slice_str, &matches)) + return llvm::createStringError( + llvm::inconvertibleErrorCode(), + "failed to match against register bitfield regex (slice: %s)", + slice_str.str().c_str()); + + llvm::StringRef reg_name_str = matches[1]; + llvm::StringRef msbit_str = matches[2]; + llvm::StringRef lsbit_str = matches[3]; + uint32_t msbit; + uint32_t lsbit; + if (!llvm::to_integer(msbit_str, msbit) || + !llvm::to_integer(lsbit_str, lsbit)) + return llvm::createStringError( + llvm::inconvertibleErrorCode(), "msbit (%s) or lsbit (%s) are invalid", + msbit_str.str().c_str(), lsbit_str.str().c_str()); + + if (msbit <= lsbit) + return llvm::createStringError(llvm::inconvertibleErrorCode(), + "msbit (%u) must be greater than lsbit (%u)", + msbit, lsbit); + + const uint32_t msbyte = msbit / 8; + const uint32_t lsbyte = lsbit / 8; + + const RegisterInfo *containing_reg_info = GetRegisterInfo(reg_name_str); + if (!containing_reg_info) + return llvm::createStringError(llvm::inconvertibleErrorCode(), + "invalid concrete register \"%s\"", + reg_name_str.str().c_str()); + + const uint32_t max_bit = containing_reg_info->byte_size * 8; + + if (msbit > max_bit) + return llvm::createStringError( + llvm::inconvertibleErrorCode(), + "msbit (%u) must be less than the bitsize of the register \"%s\" (%u)", + msbit, reg_name_str.str().c_str(), max_bit); + if (lsbit > max_bit) + return llvm::createStringError( + llvm::inconvertibleErrorCode(), + "lsbit (%u) must be less than the bitsize of the register \"%s\" (%u)", + lsbit, reg_name_str.str().c_str(), max_bit); + + m_invalidate_regs_map[containing_reg_info->kinds[eRegisterKindLLDB]] + .push_back(index); + m_value_regs_map[index].push_back( + containing_reg_info->kinds[eRegisterKindLLDB]); + m_invalidate_regs_map[index].push_back( + containing_reg_info->kinds[eRegisterKindLLDB]); + + if (byte_order == eByteOrderLittle) + return containing_reg_info->byte_offset + lsbyte; + if (byte_order == eByteOrderBig) + return containing_reg_info->byte_offset + msbyte; + llvm_unreachable("Invalid byte order"); +} + +llvm::Expected<uint32_t> DynamicRegisterInfo::ByteOffsetFromComposite( + uint32_t index, StructuredData::Array &composite_reg_list, + lldb::ByteOrder byte_order) { + const size_t num_composite_regs = composite_reg_list.GetSize(); + if (num_composite_regs == 0) + return llvm::createStringError(llvm::inconvertibleErrorCode(), + "\"composite\" list is empty"); + + uint32_t composite_offset = UINT32_MAX; + for (uint32_t composite_idx = 0; composite_idx < num_composite_regs; + ++composite_idx) { + ConstString composite_reg_name; + if (!composite_reg_list.GetItemAtIndexAsString(composite_idx, + composite_reg_name, nullptr)) + return llvm::createStringError( + llvm::inconvertibleErrorCode(), + "\"composite\" list value is not a Python string at index %d", + composite_idx); + + const RegisterInfo *composite_reg_info = + GetRegisterInfo(composite_reg_name.GetStringRef()); + if (!composite_reg_info) + return llvm::createStringError( + llvm::inconvertibleErrorCode(), + "failed to find composite register by name: \"%s\"", + composite_reg_name.GetCString()); + + composite_offset = + std::min(composite_offset, composite_reg_info->byte_offset); + m_value_regs_map[index].push_back( + composite_reg_info->kinds[eRegisterKindLLDB]); + m_invalidate_regs_map[composite_reg_info->kinds[eRegisterKindLLDB]] + .push_back(index); + m_invalidate_regs_map[index].push_back( + composite_reg_info->kinds[eRegisterKindLLDB]); + } + + return composite_offset; +} + +llvm::Expected<uint32_t> DynamicRegisterInfo::ByteOffsetFromRegInfoDict( + uint32_t index, StructuredData::Dictionary ®_info_dict, + lldb::ByteOrder byte_order) { + uint32_t byte_offset; + if (reg_info_dict.GetValueForKeyAsInteger("offset", byte_offset)) + return byte_offset; + + // 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 + llvm::StringRef slice_str; + if (reg_info_dict.GetValueForKeyAsString("slice", slice_str, nullptr)) + return ByteOffsetFromSlice(index, slice_str, byte_order); + + StructuredData::Array *composite_reg_list; + if (reg_info_dict.GetValueForKeyAsArray("composite", composite_reg_list)) + return ByteOffsetFromComposite(index, *composite_reg_list, byte_order); + + return llvm::createStringError(llvm::inconvertibleErrorCode(), + "insufficient data to calculate byte offset"); +} + size_t DynamicRegisterInfo::SetRegisterInfo(const StructuredData::Dictionary &dict, const ArchSpec &arch) { + Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_OBJECT); assert(!m_finalized); StructuredData::Array *sets = nullptr; if (dict.GetValueForKeyAsArray("sets", sets)) { @@ -81,6 +214,8 @@ DynamicRegisterInfo::SetRegisterInfo(const StructuredData::Dictionary &dict, if (!dict.GetValueForKeyAsArray("registers", regs)) return 0; + const ByteOrder byte_order = arch.GetByteOrder(); + const uint32_t num_regs = regs->GetSize(); // typedef std::map<std::string, std::vector<std::string> > // InvalidateNameMap; @@ -114,148 +249,16 @@ DynamicRegisterInfo::SetRegisterInfo(const StructuredData::Dictionary &dict, reg_info_dict->GetValueForKeyAsString("alt-name", alt_name_val, nullptr); reg_info.alt_name = alt_name_val.GetCString(); - reg_info_dict->GetValueForKeyAsInteger("offset", reg_info.byte_offset, - UINT32_MAX); - - const ByteOrder byte_order = arch.GetByteOrder(); - - if (reg_info.byte_offset == UINT32_MAX) { - // 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; - llvm::StringRef slice_str; - if (reg_info_dict->GetValueForKeyAsString("slice", slice_str, nullptr)) { - // 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( - llvm::StringRef("([A-Za-z_][A-Za-z0-9_]*)\\[([0-9]+):([0-9]+)\\]")); - llvm::SmallVector<llvm::StringRef, 4> matches; - if (g_bitfield_regex.Execute(slice_str, &matches)) { - std::string reg_name_str = matches[1].str(); - std::string msbit_str = matches[2].str(); - std::string lsbit_str = matches[3].str(); - const uint32_t msbit = - StringConvert::ToUInt32(msbit_str.c_str(), UINT32_MAX); - const uint32_t lsbit = - StringConvert::ToUInt32(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; - - const RegisterInfo *containing_reg_info = - GetRegisterInfo(reg_name_str); - 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 { - llvm_unreachable("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", - reg_name_str.c_str()); - } - } 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 match against register bitfield regex\n"); - } - } else { - StructuredData::Array *composite_reg_list = nullptr; - if (reg_info_dict->GetValueForKeyAsArray("composite", - 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) { - ConstString composite_reg_name; - if (composite_reg_list->GetItemAtIndexAsString( - composite_idx, composite_reg_name, nullptr)) { - const RegisterInfo *composite_reg_info = - GetRegisterInfo(composite_reg_name.GetStringRef()); - if (composite_reg_info) { - composite_offset = std::min(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' 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(); - reg_info_dict->DumpToStdout(); - return 0; - } + llvm::Expected<uint32_t> byte_offset = + ByteOffsetFromRegInfoDict(i, *reg_info_dict, byte_order); + if (byte_offset) + reg_info.byte_offset = byte_offset.get(); + else { + LLDB_LOG_ERROR(log, byte_offset.takeError(), + "error while parsing register {1}: {0}", reg_info.name); + Clear(); + reg_info_dict->DumpToStdout(); + return 0; } int64_t bitsize = 0; @@ -269,25 +272,6 @@ DynamicRegisterInfo::SetRegisterInfo(const StructuredData::Dictionary &dict, reg_info.byte_size = bitsize / 8; - llvm::StringRef dwarf_opcode_string; - if (reg_info_dict->GetValueForKeyAsString("dynamic_size_dwarf_expr_bytes", - dwarf_opcode_string)) { - reg_info.dynamic_size_dwarf_len = dwarf_opcode_string.size() / 2; - assert(reg_info.dynamic_size_dwarf_len > 0); - - std::vector<uint8_t> dwarf_opcode_bytes(reg_info.dynamic_size_dwarf_len); - uint32_t j; - StringExtractor opcode_extractor(dwarf_opcode_string); - uint32_t ret_val = opcode_extractor.GetHexBytesAvail(dwarf_opcode_bytes); - UNUSED_IF_ASSERT_DISABLED(ret_val); - assert(ret_val == reg_info.dynamic_size_dwarf_len); - - for (j = 0; j < reg_info.dynamic_size_dwarf_len; ++j) - m_dynamic_reg_size_map[i].push_back(dwarf_opcode_bytes[j]); - - reg_info.dynamic_size_dwarf_expr_bytes = m_dynamic_reg_size_map[i].data(); - } - llvm::StringRef format_str; if (reg_info_dict->GetValueForKeyAsString("format", format_str, nullptr)) { if (OptionArgParser::ToFormat(format_str.str().c_str(), reg_info.format, @@ -395,39 +379,47 @@ DynamicRegisterInfo::SetRegisterInfo(const StructuredData::Dictionary &dict, return m_regs.size(); } -void DynamicRegisterInfo::AddRegister(RegisterInfo ®_info, - ConstString ®_name, - ConstString ®_alt_name, - ConstString &set_name) { +size_t DynamicRegisterInfo::SetRegisterInfo( + std::vector<DynamicRegisterInfo::Register> &®s, + const ArchSpec &arch) { 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(nullptr); - 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]); - } - if (reg_info.dynamic_size_dwarf_expr_bytes) { - for (i = 0; i < reg_info.dynamic_size_dwarf_len; ++i) - m_dynamic_reg_size_map[reg_num].push_back( - reg_info.dynamic_size_dwarf_expr_bytes[i]); - reg_info.dynamic_size_dwarf_expr_bytes = - m_dynamic_reg_size_map[reg_num].data(); - } + for (auto it : llvm::enumerate(regs)) { + uint32_t local_regnum = it.index(); + const DynamicRegisterInfo::Register ® = it.value(); + + assert(reg.name); + assert(reg.set_name); + + if (!reg.value_regs.empty()) + m_value_regs_map[local_regnum] = std::move(reg.value_regs); + if (!reg.invalidate_regs.empty()) + m_invalidate_regs_map[local_regnum] = std::move(reg.invalidate_regs); + if (reg.value_reg_offset != 0) { + assert(reg.value_regs.size() == 1); + m_value_reg_offset_map[local_regnum] = reg.value_reg_offset; + } + + struct RegisterInfo reg_info { + reg.name.AsCString(), reg.alt_name.AsCString(), reg.byte_size, + reg.byte_offset, reg.encoding, reg.format, + {reg.regnum_ehframe, reg.regnum_dwarf, reg.regnum_generic, + reg.regnum_remote, local_regnum}, + // value_regs and invalidate_regs are filled by Finalize() + nullptr, nullptr + }; - m_regs.push_back(reg_info); - uint32_t set = GetRegisterSetIndexByName(set_name, true); - assert(set < m_sets.size()); - assert(set < m_set_reg_nums.size()); - assert(set < m_set_names.size()); - m_set_reg_nums[set].push_back(reg_num); + m_regs.push_back(reg_info); + + uint32_t set = GetRegisterSetIndexByName(reg.set_name, true); + assert(set < m_sets.size()); + assert(set < m_set_reg_nums.size()); + assert(set < m_set_names.size()); + m_set_reg_nums[set].push_back(local_regnum); + }; + + Finalize(arch); + return m_regs.size(); } void DynamicRegisterInfo::Finalize(const ArchSpec &arch) { @@ -442,20 +434,11 @@ void DynamicRegisterInfo::Finalize(const ArchSpec &arch) { m_sets[set].registers = m_set_reg_nums[set].data(); } - // sort and unique all value registers and make sure each is terminated with - // LLDB_INVALID_REGNUM + // make sure value_regs are 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) { - llvm::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); } @@ -603,6 +586,7 @@ void DynamicRegisterInfo::Finalize(const ArchSpec &arch) { (strcmp(reg.name, "fp") == 0)) reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FP; else if ((strcmp(reg.name, "rflags") == 0) || + (strcmp(reg.name, "eflags") == 0) || (strcmp(reg.name, "flags") == 0)) reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FLAGS; } @@ -656,15 +640,20 @@ void DynamicRegisterInfo::ConfigureOffsets() { // Now update all value_regs with each register info as needed for (auto ® : m_regs) { if (reg.value_regs != nullptr) { - // Assign a valid offset to all pseudo registers if not assigned by stub. - // Pseudo registers with value_regs list populated will share same offset - // as that of their corresponding primary register in value_regs list. + // Assign a valid offset to all pseudo registers that have only a single + // parent register in value_regs list, if not assigned by stub. Pseudo + // registers with value_regs list populated will share same offset as + // that of their corresponding parent register. if (reg.byte_offset == LLDB_INVALID_INDEX32) { uint32_t value_regnum = reg.value_regs[0]; - if (value_regnum != LLDB_INVALID_INDEX32) + if (value_regnum != LLDB_INVALID_INDEX32 && + reg.value_regs[1] == LLDB_INVALID_INDEX32) { reg.byte_offset = - GetRegisterInfoAtIndex(remote_to_local_regnum_map[value_regnum]) - ->byte_offset; + GetRegisterInfoAtIndex(value_regnum)->byte_offset; + auto it = m_value_reg_offset_map.find(reg.kinds[eRegisterKindLLDB]); + if (it != m_value_reg_offset_map.end()) + reg.byte_offset += it->second; + } } } @@ -691,12 +680,6 @@ DynamicRegisterInfo::GetRegisterInfoAtIndex(uint32_t i) const { return nullptr; } -RegisterInfo *DynamicRegisterInfo::GetRegisterInfoAtIndex(uint32_t i) { - if (i < m_regs.size()) - return &m_regs[i]; - return nullptr; -} - const RegisterInfo *DynamicRegisterInfo::GetRegisterInfo(uint32_t kind, uint32_t num) const { uint32_t reg_index = ConvertRegisterKindToRegisterNumber(kind, num); @@ -711,8 +694,9 @@ const RegisterSet *DynamicRegisterInfo::GetRegisterSet(uint32_t i) const { return nullptr; } -uint32_t DynamicRegisterInfo::GetRegisterSetIndexByName(ConstString &set_name, - bool can_create) { +uint32_t +DynamicRegisterInfo::GetRegisterSetIndexByName(const ConstString &set_name, + bool can_create) { name_collection::iterator pos, end = m_set_names.end(); for (pos = m_set_names.begin(); pos != end; ++pos) { if (*pos == set_name) @@ -745,7 +729,6 @@ void DynamicRegisterInfo::Clear() { m_set_names.clear(); m_value_regs_map.clear(); m_invalidate_regs_map.clear(); - m_dynamic_reg_size_map.clear(); m_reg_data_byte_size = 0; m_finalized = false; } @@ -809,3 +792,28 @@ DynamicRegisterInfo::GetRegisterInfo(llvm::StringRef reg_name) const { return ®_info; return nullptr; } + +void lldb_private::addSupplementaryRegister( + std::vector<DynamicRegisterInfo::Register> ®s, + DynamicRegisterInfo::Register new_reg_info) { + assert(!new_reg_info.value_regs.empty()); + const uint32_t reg_num = regs.size(); + regs.push_back(new_reg_info); + + std::map<uint32_t, std::vector<uint32_t>> new_invalidates; + for (uint32_t value_reg : new_reg_info.value_regs) { + // copy value_regs to invalidate_regs + new_invalidates[reg_num].push_back(value_reg); + + // copy invalidate_regs from the parent register + llvm::append_range(new_invalidates[reg_num], + regs[value_reg].invalidate_regs); + + // add reverse invalidate entries + for (uint32_t x : new_invalidates[reg_num]) + new_invalidates[x].push_back(reg_num); + } + + for (const auto &x : new_invalidates) + llvm::append_range(regs[x.first].invalidate_regs, x.second); +} diff --git a/contrib/llvm-project/lldb/source/Target/Language.cpp b/contrib/llvm-project/lldb/source/Target/Language.cpp index 7b35da5028ac..eee1ff1512d9 100644 --- a/contrib/llvm-project/lldb/source/Target/Language.cpp +++ b/contrib/llvm-project/lldb/source/Target/Language.cpp @@ -108,10 +108,21 @@ void Language::ForEach(std::function<bool(Language *)> callback) { } }); - std::lock_guard<std::mutex> guard(GetLanguagesMutex()); - LanguagesMap &map(GetLanguagesMap()); - for (const auto &entry : map) { - if (!callback(entry.second.get())) + // callback may call a method in Language that attempts to acquire the same + // lock (such as Language::ForEach or Language::FindPlugin). To avoid a + // deadlock, we do not use callback while holding the lock. + std::vector<Language *> loaded_plugins; + { + std::lock_guard<std::mutex> guard(GetLanguagesMutex()); + LanguagesMap &map(GetLanguagesMap()); + for (const auto &entry : map) { + if (entry.second) + loaded_plugins.push_back(entry.second.get()); + } + } + + for (auto *lang : loaded_plugins) { + if (!callback(lang)) break; } } diff --git a/contrib/llvm-project/lldb/source/Target/ModuleCache.cpp b/contrib/llvm-project/lldb/source/Target/ModuleCache.cpp index dcdc0772b31a..7143fcd2707c 100644 --- a/contrib/llvm-project/lldb/source/Target/ModuleCache.cpp +++ b/contrib/llvm-project/lldb/source/Target/ModuleCache.cpp @@ -159,7 +159,7 @@ ModuleLock::ModuleLock(const FileSpec &root_dir_spec, const UUID &uuid, m_file_spec = JoinPath(lock_dir_spec, uuid.GetAsString().c_str()); auto file = FileSystem::Instance().Open( - m_file_spec, File::eOpenOptionWrite | File::eOpenOptionCanCreate | + m_file_spec, File::eOpenOptionWriteOnly | File::eOpenOptionCanCreate | File::eOpenOptionCloseOnExec); if (file) m_file_up = std::move(file.get()); diff --git a/contrib/llvm-project/lldb/source/Target/OperatingSystem.cpp b/contrib/llvm-project/lldb/source/Target/OperatingSystem.cpp index 033a806460da..75762c05151d 100644 --- a/contrib/llvm-project/lldb/source/Target/OperatingSystem.cpp +++ b/contrib/llvm-project/lldb/source/Target/OperatingSystem.cpp @@ -17,10 +17,9 @@ OperatingSystem *OperatingSystem::FindPlugin(Process *process, const char *plugin_name) { OperatingSystemCreateInstance create_callback = nullptr; if (plugin_name) { - ConstString const_plugin_name(plugin_name); create_callback = PluginManager::GetOperatingSystemCreateCallbackForPluginName( - const_plugin_name); + plugin_name); if (create_callback) { std::unique_ptr<OperatingSystem> instance_up( create_callback(process, true)); diff --git a/contrib/llvm-project/lldb/source/Target/PathMappingList.cpp b/contrib/llvm-project/lldb/source/Target/PathMappingList.cpp index b660c310ef31..e49f6213cf27 100644 --- a/contrib/llvm-project/lldb/source/Target/PathMappingList.cpp +++ b/contrib/llvm-project/lldb/source/Target/PathMappingList.cpp @@ -30,11 +30,11 @@ namespace { // with the raw path pair, which doesn't work anymore because the paths have // been normalized when the debug info was loaded. So we need to store // nomalized path pairs to ensure things match up. - ConstString NormalizePath(ConstString path) { - // If we use "path" to construct a FileSpec, it will normalize the path for - // us. We then grab the string and turn it back into a ConstString. - return ConstString(FileSpec(path.GetStringRef()).GetPath()); - } +std::string NormalizePath(llvm::StringRef path) { + // If we use "path" to construct a FileSpec, it will normalize the path for + // us. We then grab the string. + return FileSpec(path).GetPath(); +} } // PathMappingList constructor PathMappingList::PathMappingList() : m_pairs() {} @@ -59,8 +59,8 @@ const PathMappingList &PathMappingList::operator=(const PathMappingList &rhs) { PathMappingList::~PathMappingList() = default; -void PathMappingList::Append(ConstString path, - ConstString replacement, bool notify) { +void PathMappingList::Append(llvm::StringRef path, llvm::StringRef replacement, + bool notify) { ++m_mod_id; m_pairs.emplace_back(pair(NormalizePath(path), NormalizePath(replacement))); if (notify && m_callback) @@ -78,9 +78,8 @@ void PathMappingList::Append(const PathMappingList &rhs, bool notify) { } } -void PathMappingList::Insert(ConstString path, - ConstString replacement, uint32_t index, - bool notify) { +void PathMappingList::Insert(llvm::StringRef path, llvm::StringRef replacement, + uint32_t index, bool notify) { ++m_mod_id; iterator insert_iter; if (index >= m_pairs.size()) @@ -93,9 +92,8 @@ void PathMappingList::Insert(ConstString path, m_callback(*this, m_callback_baton); } -bool PathMappingList::Replace(ConstString path, - ConstString replacement, uint32_t index, - bool notify) { +bool PathMappingList::Replace(llvm::StringRef path, llvm::StringRef replacement, + uint32_t index, bool notify) { if (index >= m_pairs.size()) return false; ++m_mod_id; @@ -218,18 +216,22 @@ bool PathMappingList::ReverseRemapPath(const FileSpec &file, FileSpec &fixed) co } llvm::Optional<FileSpec> PathMappingList::FindFile(const FileSpec &orig_spec) const { - if (auto remapped = RemapPath(orig_spec.GetPath(), /*only_if_exists=*/true)) + // We must normalize the orig_spec again using the host's path style, + // otherwise there will be mismatch between the host and remote platform + // if they use different path styles. + if (auto remapped = RemapPath(NormalizePath(orig_spec.GetPath()), + /*only_if_exists=*/true)) return remapped; return {}; } -bool PathMappingList::Replace(ConstString path, - ConstString new_path, bool notify) { +bool PathMappingList::Replace(llvm::StringRef path, llvm::StringRef new_path, + bool notify) { uint32_t idx = FindIndexForPath(path); if (idx < m_pairs.size()) { ++m_mod_id; - m_pairs[idx].second = new_path; + m_pairs[idx].second = ConstString(new_path); if (notify && m_callback) m_callback(*this, m_callback_baton); return true; @@ -285,8 +287,8 @@ bool PathMappingList::GetPathsAtIndex(uint32_t idx, ConstString &path, return false; } -uint32_t PathMappingList::FindIndexForPath(ConstString orig_path) const { - const ConstString path = NormalizePath(orig_path); +uint32_t PathMappingList::FindIndexForPath(llvm::StringRef orig_path) const { + const ConstString path = ConstString(NormalizePath(orig_path)); const_iterator pos; const_iterator begin = m_pairs.begin(); const_iterator end = m_pairs.end(); diff --git a/contrib/llvm-project/lldb/source/Target/Platform.cpp b/contrib/llvm-project/lldb/source/Target/Platform.cpp index a77ecddfbab6..bd455310f08e 100644 --- a/contrib/llvm-project/lldb/source/Target/Platform.cpp +++ b/contrib/llvm-project/lldb/source/Target/Platform.cpp @@ -155,9 +155,9 @@ void Platform::Terminate() { } } -const PlatformPropertiesSP &Platform::GetGlobalPlatformProperties() { - static const auto g_settings_sp(std::make_shared<PlatformProperties>()); - return g_settings_sp; +PlatformProperties &Platform::GetGlobalPlatformProperties() { + static PlatformProperties g_settings; + return g_settings; } void Platform::SetHostPlatform(const lldb::PlatformSP &platform_sp) { @@ -294,8 +294,8 @@ PlatformSP Platform::Create(ConstString name, Status &error) { if (name == g_host_platform_name) return GetHostPlatform(); - create_callback = - PluginManager::GetPlatformCreateCallbackForPluginName(name); + create_callback = PluginManager::GetPlatformCreateCallbackForPluginName( + name.GetStringRef()); if (create_callback) platform_sp = create_callback(true, nullptr); else @@ -395,18 +395,10 @@ Platform::Platform(bool is_host) LLDB_LOGF(log, "%p Platform::Platform()", static_cast<void *>(this)); } -/// Destructor. -/// -/// The destructor is virtual since this class is designed to be -/// inherited from by the plug-in instance. -Platform::~Platform() { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_OBJECT)); - LLDB_LOGF(log, "%p Platform::~Platform()", static_cast<void *>(this)); -} +Platform::~Platform() = default; void Platform::GetStatus(Stream &strm) { - std::string s; - strm.Printf(" Platform: %s\n", GetPluginName().GetCString()); + strm.Format(" Platform: {0}\n", GetPluginName()); ArchSpec arch(GetSystemArchitecture()); if (arch.IsValid()) { @@ -421,8 +413,8 @@ void Platform::GetStatus(Stream &strm) { if (!os_version.empty()) { strm.Format("OS Version: {0}", os_version.getAsString()); - if (GetOSBuildString(s)) - strm.Printf(" (%s)", s.c_str()); + if (llvm::Optional<std::string> s = GetOSBuildString()) + strm.Format(" ({0})", *s); strm.EOL(); } @@ -447,8 +439,8 @@ void Platform::GetStatus(Stream &strm) { if (!specific_info.empty()) strm.Printf("Platform-specific connection: %s\n", specific_info.c_str()); - if (GetOSKernelDescription(s)) - strm.Printf(" Kernel: %s\n", s.c_str()); + if (llvm::Optional<std::string> s = GetOSKernelDescription()) + strm.Format(" Kernel: {0}\n", *s); } llvm::VersionTuple Platform::GetOSVersion(Process *process) { @@ -493,28 +485,16 @@ llvm::VersionTuple Platform::GetOSVersion(Process *process) { return llvm::VersionTuple(); } -bool Platform::GetOSBuildString(std::string &s) { - s.clear(); - +llvm::Optional<std::string> Platform::GetOSBuildString() { if (IsHost()) -#if !defined(__linux__) - return HostInfo::GetOSBuildString(s); -#else - return false; -#endif - else - return GetRemoteOSBuildString(s); + return HostInfo::GetOSBuildString(); + return GetRemoteOSBuildString(); } -bool Platform::GetOSKernelDescription(std::string &s) { +llvm::Optional<std::string> Platform::GetOSKernelDescription() { if (IsHost()) -#if !defined(__linux__) - return HostInfo::GetOSKernelDescription(s); -#else - return false; -#endif - else - return GetRemoteOSKernelDescription(s); + return HostInfo::GetOSKernelDescription(); + return GetRemoteOSKernelDescription(); } void Platform::AddClangModuleCompilationOptions( @@ -769,9 +749,8 @@ Status Platform::MakeDirectory(const FileSpec &file_spec, return llvm::sys::fs::create_directory(file_spec.GetPath(), permissions); else { Status error; - error.SetErrorStringWithFormat("remote platform %s doesn't support %s", - GetPluginName().GetCString(), - LLVM_PRETTY_FUNCTION); + error.SetErrorStringWithFormatv("remote platform {0} doesn't support {1}", + GetPluginName(), LLVM_PRETTY_FUNCTION); return error; } } @@ -785,9 +764,8 @@ Status Platform::GetFilePermissions(const FileSpec &file_spec, return Status(Value.getError()); } else { Status error; - error.SetErrorStringWithFormat("remote platform %s doesn't support %s", - GetPluginName().GetCString(), - LLVM_PRETTY_FUNCTION); + error.SetErrorStringWithFormatv("remote platform {0} doesn't support {1}", + GetPluginName(), LLVM_PRETTY_FUNCTION); return error; } } @@ -799,14 +777,13 @@ Status Platform::SetFilePermissions(const FileSpec &file_spec, return llvm::sys::fs::setPermissions(file_spec.GetPath(), Perms); } else { Status error; - error.SetErrorStringWithFormat("remote platform %s doesn't support %s", - GetPluginName().GetCString(), - LLVM_PRETTY_FUNCTION); + error.SetErrorStringWithFormatv("remote platform {0} doesn't support {1}", + GetPluginName(), LLVM_PRETTY_FUNCTION); return error; } } -ConstString Platform::GetName() { return GetPluginName(); } +ConstString Platform::GetName() { return ConstString(GetPluginName()); } const char *Platform::GetHostname() { if (IsHost()) @@ -856,6 +833,7 @@ Platform::ResolveExecutable(const ModuleSpec &module_spec, lldb::ModuleSP &exe_module_sp, const FileSpecList *module_search_paths_ptr) { Status error; + if (FileSystem::Instance().Exists(module_spec.GetFileSpec())) { if (module_spec.GetArchitecture().IsValid()) { error = ModuleList::GetSharedModule(module_spec, exe_module_sp, @@ -866,9 +844,8 @@ Platform::ResolveExecutable(const ModuleSpec &module_spec, // architectures that we should be using (in the correct order) and see // if we can find a match that way ModuleSpec arch_module_spec(module_spec); - for (uint32_t idx = 0; GetSupportedArchitectureAtIndex( - idx, arch_module_spec.GetArchitecture()); - ++idx) { + for (const ArchSpec &arch : GetSupportedArchitectures()) { + arch_module_spec.GetArchitecture() = arch; error = ModuleList::GetSharedModule(arch_module_spec, exe_module_sp, module_search_paths_ptr, nullptr, nullptr); @@ -878,9 +855,74 @@ Platform::ResolveExecutable(const ModuleSpec &module_spec, } } } else { - error.SetErrorStringWithFormat("'%s' does not exist", - module_spec.GetFileSpec().GetPath().c_str()); + error.SetErrorStringWithFormat( + "'%s' does not exist", module_spec.GetFileSpec().GetPath().c_str()); + } + return error; +} + +Status +Platform::ResolveRemoteExecutable(const ModuleSpec &module_spec, + lldb::ModuleSP &exe_module_sp, + const FileSpecList *module_search_paths_ptr) { + Status error; + + // We may connect to a process and use the provided executable (Don't use + // local $PATH). + ModuleSpec resolved_module_spec(module_spec); + + // Resolve any executable within a bundle on MacOSX + Host::ResolveExecutableInBundle(resolved_module_spec.GetFileSpec()); + + if (FileSystem::Instance().Exists(resolved_module_spec.GetFileSpec()) || + module_spec.GetUUID().IsValid()) { + if (resolved_module_spec.GetArchitecture().IsValid() || + resolved_module_spec.GetUUID().IsValid()) { + error = ModuleList::GetSharedModule(resolved_module_spec, exe_module_sp, + module_search_paths_ptr, nullptr, + nullptr); + + if (exe_module_sp && exe_module_sp->GetObjectFile()) + return error; + exe_module_sp.reset(); + } + // No valid architecture was specified or the exact arch wasn't found so + // ask the platform for the architectures that we should be using (in the + // correct order) and see if we can find a match that way + StreamString arch_names; + llvm::ListSeparator LS; + for (const ArchSpec &arch : GetSupportedArchitectures()) { + resolved_module_spec.GetArchitecture() = arch; + error = ModuleList::GetSharedModule(resolved_module_spec, exe_module_sp, + module_search_paths_ptr, nullptr, + nullptr); + // Did we find an executable using one of the + if (error.Success()) { + if (exe_module_sp && exe_module_sp->GetObjectFile()) + break; + else + error.SetErrorToGenericError(); + } + + arch_names << LS << arch.GetArchitectureName(); + } + + if (error.Fail() || !exe_module_sp) { + if (FileSystem::Instance().Readable(resolved_module_spec.GetFileSpec())) { + error.SetErrorStringWithFormatv( + "'{0}' doesn't contain any '{1}' platform architectures: {2}", + resolved_module_spec.GetFileSpec(), GetPluginName(), + arch_names.GetData()); + } else { + error.SetErrorStringWithFormatv("'{0}' is not readable", + resolved_module_spec.GetFileSpec()); + } + } + } else { + error.SetErrorStringWithFormatv("'{0}' does not exist", + resolved_module_spec.GetFileSpec()); } + return error; } @@ -966,26 +1008,27 @@ ArchSpec Platform::GetAugmentedArchSpec(llvm::StringRef triple) { Status Platform::ConnectRemote(Args &args) { Status error; if (IsHost()) - error.SetErrorStringWithFormat("The currently selected platform (%s) is " - "the host platform and is always connected.", - GetPluginName().GetCString()); + error.SetErrorStringWithFormatv( + "The currently selected platform ({0}) is " + "the host platform and is always connected.", + GetPluginName()); else - error.SetErrorStringWithFormat( - "Platform::ConnectRemote() is not supported by %s", - GetPluginName().GetCString()); + error.SetErrorStringWithFormatv( + "Platform::ConnectRemote() is not supported by {0}", GetPluginName()); return error; } Status Platform::DisconnectRemote() { Status error; if (IsHost()) - error.SetErrorStringWithFormat("The currently selected platform (%s) is " - "the host platform and is always connected.", - GetPluginName().GetCString()); + error.SetErrorStringWithFormatv( + "The currently selected platform ({0}) is " + "the host platform and is always connected.", + GetPluginName()); else - error.SetErrorStringWithFormat( - "Platform::DisconnectRemote() is not supported by %s", - GetPluginName().GetCString()); + error.SetErrorStringWithFormatv( + "Platform::DisconnectRemote() is not supported by {0}", + GetPluginName()); return error; } @@ -1066,36 +1109,19 @@ Status Platform::KillProcess(const lldb::pid_t pid) { Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM)); LLDB_LOGF(log, "Platform::%s, pid %" PRIu64, __FUNCTION__, pid); - // Try to find a process plugin to handle this Kill request. If we can't, - // fall back to the default OS implementation. - size_t num_debuggers = Debugger::GetNumDebuggers(); - for (size_t didx = 0; didx < num_debuggers; ++didx) { - DebuggerSP debugger = Debugger::GetDebuggerAtIndex(didx); - lldb_private::TargetList &targets = debugger->GetTargetList(); - for (int tidx = 0; tidx < targets.GetNumTargets(); ++tidx) { - ProcessSP process = targets.GetTargetAtIndex(tidx)->GetProcessSP(); - if (process->GetID() == pid) - return process->Destroy(true); - } - } - if (!IsHost()) { return Status( - "base lldb_private::Platform class can't kill remote processes unless " - "they are controlled by a process plugin"); + "base lldb_private::Platform class can't kill remote processes"); } - Host::Kill(pid, SIGTERM); + Host::Kill(pid, SIGKILL); return Status(); } -lldb::ProcessSP -Platform::DebugProcess(ProcessLaunchInfo &launch_info, Debugger &debugger, - Target *target, // Can be nullptr, if nullptr create a - // new target, else use existing one - Status &error) { +lldb::ProcessSP Platform::DebugProcess(ProcessLaunchInfo &launch_info, + Debugger &debugger, Target &target, + Status &error) { Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM)); - LLDB_LOGF(log, "Platform::%s entered (target %p)", __FUNCTION__, - static_cast<void *>(target)); + LLDB_LOG(log, "target = {0})", &target); ProcessSP process_sp; // Make sure we stop at the entry point @@ -1117,7 +1143,7 @@ Platform::DebugProcess(ProcessLaunchInfo &launch_info, Debugger &debugger, filter_callback = get_filter_func(++i, iteration_complete)) { if (filter_callback) { // Give this ProcessLaunchInfo filter a chance to adjust the launch info. - error = (*filter_callback)(launch_info, target); + error = (*filter_callback)(launch_info, &target); if (!error.Success()) { LLDB_LOGF(log, "Platform::%s() StructuredDataPlugin launch " @@ -1135,10 +1161,10 @@ Platform::DebugProcess(ProcessLaunchInfo &launch_info, Debugger &debugger, __FUNCTION__, launch_info.GetProcessID()); if (launch_info.GetProcessID() != LLDB_INVALID_PROCESS_ID) { ProcessAttachInfo attach_info(launch_info); - process_sp = Attach(attach_info, debugger, target, error); + process_sp = Attach(attach_info, debugger, &target, error); if (process_sp) { - LLDB_LOGF(log, "Platform::%s Attach() succeeded, Process plugin: %s", - __FUNCTION__, process_sp->GetPluginName().AsCString()); + LLDB_LOG(log, "Attach() succeeded, Process plugin: {0}", + process_sp->GetPluginName()); launch_info.SetHijackListener(attach_info.GetHijackListener()); // Since we attached to the process, it will think it needs to detach @@ -1149,7 +1175,7 @@ Platform::DebugProcess(ProcessLaunchInfo &launch_info, Debugger &debugger, // If we didn't have any file actions, the pseudo terminal might have // been used where the secondary side was given as the file to open for - // stdin/out/err after we have already opened the master so we can + // stdin/out/err after we have already opened the primary so we can // read/write stdin/out/err. int pty_fd = launch_info.GetPTY().ReleasePrimaryFileDescriptor(); if (pty_fd != PseudoTerminal::invalid_fd) { @@ -1183,6 +1209,35 @@ Platform::GetPlatformForArchitecture(const ArchSpec &arch, return platform_sp; } +std::vector<ArchSpec> +Platform::CreateArchList(llvm::ArrayRef<llvm::Triple::ArchType> archs, + llvm::Triple::OSType os) { + std::vector<ArchSpec> list; + for(auto arch : archs) { + llvm::Triple triple; + triple.setArch(arch); + triple.setOS(os); + list.push_back(ArchSpec(triple)); + } + return list; +} + +bool Platform::GetSupportedArchitectureAtIndex(uint32_t idx, ArchSpec &arch) { + const auto &archs = GetSupportedArchitectures(); + if (idx >= archs.size()) + return false; + arch = archs[idx]; + return true; +} + +std::vector<ArchSpec> Platform::GetSupportedArchitectures() { + std::vector<ArchSpec> result; + ArchSpec arch; + for (uint32_t idx = 0; GetSupportedArchitectureAtIndex(idx, arch); ++idx) + result.push_back(arch); + return result; +} + /// Lets a platform answer if it is compatible with a given /// architecture and the target triple contained within. bool Platform::IsCompatibleArchitecture(const ArchSpec &arch, @@ -1191,26 +1246,13 @@ bool Platform::IsCompatibleArchitecture(const ArchSpec &arch, // If the architecture is invalid, we must answer true... if (arch.IsValid()) { ArchSpec platform_arch; - // Try for an exact architecture match first. - if (exact_arch_match) { - for (uint32_t arch_idx = 0; - GetSupportedArchitectureAtIndex(arch_idx, platform_arch); - ++arch_idx) { - if (arch.IsExactMatch(platform_arch)) { - if (compatible_arch_ptr) - *compatible_arch_ptr = platform_arch; - return true; - } - } - } else { - for (uint32_t arch_idx = 0; - GetSupportedArchitectureAtIndex(arch_idx, platform_arch); - ++arch_idx) { - if (arch.IsCompatibleMatch(platform_arch)) { - if (compatible_arch_ptr) - *compatible_arch_ptr = platform_arch; - return true; - } + auto match = exact_arch_match ? &ArchSpec::IsExactMatch + : &ArchSpec::IsCompatibleMatch; + for (const ArchSpec &platform_arch : GetSupportedArchitectures()) { + if ((arch.*match)(platform_arch)) { + if (compatible_arch_ptr) + *compatible_arch_ptr = platform_arch; + return true; } } } @@ -1225,7 +1267,7 @@ Status Platform::PutFile(const FileSpec &source, const FileSpec &destination, LLDB_LOGF(log, "[PutFile] Using block by block transfer....\n"); auto source_open_options = - File::eOpenOptionRead | File::eOpenOptionCloseOnExec; + File::eOpenOptionReadOnly | File::eOpenOptionCloseOnExec; namespace fs = llvm::sys::fs; if (fs::is_symlink_file(source.GetPath())) source_open_options |= File::eOpenOptionDontFollowSymlinks; @@ -1240,7 +1282,7 @@ Status Platform::PutFile(const FileSpec &source, const FileSpec &destination, permissions = lldb::eFilePermissionsFileDefault; lldb::user_id_t dest_file = OpenFile( - destination, File::eOpenOptionCanCreate | File::eOpenOptionWrite | + destination, File::eOpenOptionCanCreate | File::eOpenOptionWriteOnly | File::eOpenOptionTruncate | File::eOpenOptionCloseOnExec, permissions, error); LLDB_LOGF(log, "dest_file = %" PRIu64 "\n", dest_file); @@ -1517,12 +1559,13 @@ const std::vector<ConstString> &Platform::GetTrapHandlerSymbolNames() { return m_trap_handlers; } -Status Platform::GetCachedExecutable( - ModuleSpec &module_spec, lldb::ModuleSP &module_sp, - const FileSpecList *module_search_paths_ptr, Platform &remote_platform) { +Status +Platform::GetCachedExecutable(ModuleSpec &module_spec, + lldb::ModuleSP &module_sp, + const FileSpecList *module_search_paths_ptr) { const auto platform_spec = module_spec.GetFileSpec(); - const auto error = LoadCachedExecutable( - module_spec, module_sp, module_search_paths_ptr, remote_platform); + const auto error = + LoadCachedExecutable(module_spec, module_sp, module_search_paths_ptr); if (error.Success()) { module_spec.GetFileSpec() = module_sp->GetFileSpec(); module_spec.GetPlatformFileSpec() = platform_spec; @@ -1531,15 +1574,17 @@ Status Platform::GetCachedExecutable( return error; } -Status Platform::LoadCachedExecutable( - const ModuleSpec &module_spec, lldb::ModuleSP &module_sp, - const FileSpecList *module_search_paths_ptr, Platform &remote_platform) { - return GetRemoteSharedModule(module_spec, nullptr, module_sp, - [&](const ModuleSpec &spec) { - return remote_platform.ResolveExecutable( - spec, module_sp, module_search_paths_ptr); - }, - nullptr); +Status +Platform::LoadCachedExecutable(const ModuleSpec &module_spec, + lldb::ModuleSP &module_sp, + const FileSpecList *module_search_paths_ptr) { + return GetRemoteSharedModule( + module_spec, nullptr, module_sp, + [&](const ModuleSpec &spec) { + return ResolveRemoteExecutable(spec, module_sp, + module_search_paths_ptr); + }, + nullptr); } Status Platform::GetRemoteSharedModule(const ModuleSpec &module_spec, @@ -1568,9 +1613,8 @@ Status Platform::GetRemoteSharedModule(const ModuleSpec &module_spec, // architectures that we should be using (in the correct order) and see if // we can find a match that way ModuleSpec arch_module_spec(module_spec); - for (uint32_t idx = 0; GetSupportedArchitectureAtIndex( - idx, arch_module_spec.GetArchitecture()); - ++idx) { + for (const ArchSpec &arch : GetSupportedArchitectures()) { + arch_module_spec.GetArchitecture() = arch; error = ModuleList::GetSharedModule(arch_module_spec, module_sp, nullptr, nullptr, nullptr); // Did we find an executable using one of the @@ -1619,8 +1663,8 @@ Status Platform::GetRemoteSharedModule(const ModuleSpec &module_spec, bool Platform::GetCachedSharedModule(const ModuleSpec &module_spec, lldb::ModuleSP &module_sp, bool *did_create_ptr) { - if (IsHost() || !GetGlobalPlatformProperties()->GetUseModuleCache() || - !GetGlobalPlatformProperties()->GetModuleCacheDirectory()) + if (IsHost() || !GetGlobalPlatformProperties().GetUseModuleCache() || + !GetGlobalPlatformProperties().GetModuleCacheDirectory()) return false; Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM); @@ -1663,7 +1707,7 @@ Status Platform::DownloadModuleSlice(const FileSpec &src_file_spec, return error; } - auto src_fd = OpenFile(src_file_spec, File::eOpenOptionRead, + auto src_fd = OpenFile(src_file_spec, File::eOpenOptionReadOnly, lldb::eFilePermissionsFileDefault, error); if (error.Fail()) { @@ -1704,7 +1748,7 @@ Status Platform::DownloadSymbolFile(const lldb::ModuleSP &module_sp, } FileSpec Platform::GetModuleCacheRoot() { - auto dir_spec = GetGlobalPlatformProperties()->GetModuleCacheDirectory(); + auto dir_spec = GetGlobalPlatformProperties().GetModuleCacheDirectory(); dir_spec.AppendPathComponent(GetName().AsCString()); return dir_spec; } diff --git a/contrib/llvm-project/lldb/source/Target/Process.cpp b/contrib/llvm-project/lldb/source/Target/Process.cpp index 8ecc66b592ea..84dc2b94a0eb 100644 --- a/contrib/llvm-project/lldb/source/Target/Process.cpp +++ b/contrib/llvm-project/lldb/source/Target/Process.cpp @@ -110,6 +110,19 @@ public: } }; +static constexpr OptionEnumValueElement g_follow_fork_mode_values[] = { + { + eFollowParent, + "parent", + "Continue tracing the parent process and detach the child.", + }, + { + eFollowChild, + "child", + "Trace the child process and detach the parent.", + }, +}; + #define LLDB_PROPERTIES_process #include "TargetProperties.inc" @@ -153,10 +166,10 @@ ProcessProperties::ProcessProperties(lldb_private::Process *process) m_collection_sp->Initialize(g_process_properties); m_collection_sp->AppendProperty( ConstString("thread"), ConstString("Settings specific to threads."), - true, Thread::GetGlobalProperties()->GetValueProperties()); + true, Thread::GetGlobalProperties().GetValueProperties()); } else { m_collection_sp = - OptionValueProperties::CreateLocalCopy(*Process::GetGlobalProperties()); + OptionValueProperties::CreateLocalCopy(Process::GetGlobalProperties()); m_collection_sp->SetValueChangedCallback( ePropertyPythonOSPluginPath, [this] { m_process->LoadOperatingSystemPlugin(true); }); @@ -334,6 +347,12 @@ void ProcessProperties::SetOSPluginReportsAllThreads(bool does_report) { nullptr, ePropertyOSPluginReportsAllThreads, does_report); } +FollowForkMode ProcessProperties::GetFollowForkMode() const { + const uint32_t idx = ePropertyFollowForkMode; + return (FollowForkMode)m_collection_sp->GetPropertyAtIndexAsEnumeration( + nullptr, idx, g_process_properties[idx].default_uint_value); +} + ProcessSP Process::FindPlugin(lldb::TargetSP target_sp, llvm::StringRef plugin_name, ListenerSP listener_sp, @@ -344,9 +363,8 @@ ProcessSP Process::FindPlugin(lldb::TargetSP target_sp, ProcessSP process_sp; ProcessCreateInstance create_callback = nullptr; if (!plugin_name.empty()) { - ConstString const_plugin_name(plugin_name); create_callback = - PluginManager::GetProcessCreateCallbackForPluginName(const_plugin_name); + PluginManager::GetProcessCreateCallbackForPluginName(plugin_name); if (create_callback) { process_sp = create_callback(target_sp, listener_sp, crash_file_path, can_connect); @@ -481,12 +499,12 @@ Process::~Process() { m_thread_list.Clear(); } -const ProcessPropertiesSP &Process::GetGlobalProperties() { +ProcessProperties &Process::GetGlobalProperties() { // NOTE: intentional leak so we don't crash if global destructor chain gets // called as other threads still use the result of this function - static ProcessPropertiesSP *g_settings_sp_ptr = - new ProcessPropertiesSP(new ProcessProperties(nullptr)); - return *g_settings_sp_ptr; + static ProcessProperties *g_settings_ptr = + new ProcessProperties(nullptr); + return *g_settings_ptr; } void Process::Finalize() { @@ -1278,6 +1296,17 @@ StateType Process::GetState() { } void Process::SetPublicState(StateType new_state, bool restarted) { + const bool new_state_is_stopped = StateIsStoppedState(new_state, false); + if (new_state_is_stopped) { + // This will only set the time if the public stop time has no value, so + // it is ok to call this multiple times. With a public stop we can't look + // at the stop ID because many private stops might have happened, so we + // can't check for a stop ID of zero. This allows the "statistics" command + // to dump the time it takes to reach somewhere in your code, like a + // breakpoint you set. + GetTarget().GetStatistics().SetFirstPublicStopTime(); + } + Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_STATE | LIBLLDB_LOG_PROCESS)); LLDB_LOGF(log, "Process::SetPublicState (state = %s, restarted = %i)", @@ -1296,7 +1325,6 @@ void Process::SetPublicState(StateType new_state, bool restarted) { m_public_run_lock.SetStopped(); } else { const bool old_state_is_stopped = StateIsStoppedState(old_state, false); - const bool new_state_is_stopped = StateIsStoppedState(new_state, false); if ((old_state_is_stopped != new_state_is_stopped)) { if (new_state_is_stopped && !restarted) { LLDB_LOGF(log, "Process::SetPublicState (%s) -- unlocking run lock", @@ -1427,7 +1455,9 @@ void Process::SetPrivateState(StateType new_state) { // before we get here. m_thread_list.DidStop(); - m_mod_id.BumpStopID(); + if (m_mod_id.BumpStopID() == 0) + GetTarget().GetStatistics().SetFirstPrivateStopTime(); + if (!m_mod_id.IsLastResumeForUserExpression()) m_mod_id.SetStopEventForLastNaturalStopID(event_sp); m_memory_cache.Clear(); @@ -1953,57 +1983,6 @@ size_t Process::ReadCStringFromMemory(addr_t addr, std::string &out_str, return out_str.size(); } -size_t Process::ReadStringFromMemory(addr_t addr, char *dst, size_t max_bytes, - Status &error, size_t type_width) { - size_t total_bytes_read = 0; - if (dst && max_bytes && type_width && max_bytes >= type_width) { - // Ensure a null terminator independent of the number of bytes that is - // read. - memset(dst, 0, max_bytes); - size_t bytes_left = max_bytes - type_width; - - const char terminator[4] = {'\0', '\0', '\0', '\0'}; - assert(sizeof(terminator) >= type_width && "Attempting to validate a " - "string with more than 4 bytes " - "per character!"); - - addr_t curr_addr = addr; - const size_t cache_line_size = m_memory_cache.GetMemoryCacheLineSize(); - char *curr_dst = dst; - - error.Clear(); - while (bytes_left > 0 && error.Success()) { - addr_t cache_line_bytes_left = - cache_line_size - (curr_addr % cache_line_size); - addr_t bytes_to_read = - std::min<addr_t>(bytes_left, cache_line_bytes_left); - size_t bytes_read = ReadMemory(curr_addr, curr_dst, bytes_to_read, error); - - if (bytes_read == 0) - break; - - // Search for a null terminator of correct size and alignment in - // bytes_read - size_t aligned_start = total_bytes_read - total_bytes_read % type_width; - for (size_t i = aligned_start; - i + type_width <= total_bytes_read + bytes_read; i += type_width) - if (::memcmp(&dst[i], terminator, type_width) == 0) { - error.Clear(); - return i; - } - - total_bytes_read += bytes_read; - curr_dst += bytes_read; - curr_addr += bytes_read; - bytes_left -= bytes_read; - } - } else { - if (max_bytes) - error.SetErrorString("invalid arguments"); - } - return total_bytes_read; -} - // Deprecated in favor of ReadStringFromMemory which has wchar support and // correct code to find null terminators. size_t Process::ReadCStringFromMemory(addr_t addr, char *dst, @@ -2463,115 +2442,125 @@ Status Process::Launch(ProcessLaunchInfo &launch_info) { m_process_input_reader.reset(); Module *exe_module = GetTarget().GetExecutableModulePointer(); - if (!exe_module) { - error.SetErrorString("executable module does not exist"); - return error; - } - char local_exec_file_path[PATH_MAX]; - char platform_exec_file_path[PATH_MAX]; - exe_module->GetFileSpec().GetPath(local_exec_file_path, - sizeof(local_exec_file_path)); - exe_module->GetPlatformFileSpec().GetPath(platform_exec_file_path, - sizeof(platform_exec_file_path)); - if (FileSystem::Instance().Exists(exe_module->GetFileSpec())) { + // The "remote executable path" is hooked up to the local Executable + // module. But we should be able to debug a remote process even if the + // executable module only exists on the remote. However, there needs to + // be a way to express this path, without actually having a module. + // The way to do that is to set the ExecutableFile in the LaunchInfo. + // Figure that out here: + + FileSpec exe_spec_to_use; + if (!exe_module) { + if (!launch_info.GetExecutableFile()) { + error.SetErrorString("executable module does not exist"); + return error; + } + exe_spec_to_use = launch_info.GetExecutableFile(); + } else + exe_spec_to_use = exe_module->GetFileSpec(); + + if (exe_module && FileSystem::Instance().Exists(exe_module->GetFileSpec())) { // Install anything that might need to be installed prior to launching. // For host systems, this will do nothing, but if we are connected to a // remote platform it will install any needed binaries error = GetTarget().Install(&launch_info); if (error.Fail()) return error; + } + // Listen and queue events that are broadcasted during the process launch. + ListenerSP listener_sp(Listener::MakeListener("LaunchEventHijack")); + HijackProcessEvents(listener_sp); + auto on_exit = llvm::make_scope_exit([this]() { RestoreProcessEvents(); }); - // Listen and queue events that are broadcasted during the process launch. - ListenerSP listener_sp(Listener::MakeListener("LaunchEventHijack")); - HijackProcessEvents(listener_sp); - auto on_exit = llvm::make_scope_exit([this]() { RestoreProcessEvents(); }); + if (PrivateStateThreadIsValid()) + PausePrivateStateThread(); - if (PrivateStateThreadIsValid()) - PausePrivateStateThread(); + error = WillLaunch(exe_module); + if (error.Success()) { + const bool restarted = false; + SetPublicState(eStateLaunching, restarted); + m_should_detach = false; - error = WillLaunch(exe_module); - if (error.Success()) { - const bool restarted = false; - SetPublicState(eStateLaunching, restarted); - m_should_detach = false; + if (m_public_run_lock.TrySetRunning()) { + // Now launch using these arguments. + error = DoLaunch(exe_module, launch_info); + } else { + // This shouldn't happen + error.SetErrorString("failed to acquire process run lock"); + } - if (m_public_run_lock.TrySetRunning()) { - // Now launch using these arguments. - error = DoLaunch(exe_module, launch_info); - } else { - // This shouldn't happen - error.SetErrorString("failed to acquire process run lock"); + if (error.Fail()) { + if (GetID() != LLDB_INVALID_PROCESS_ID) { + SetID(LLDB_INVALID_PROCESS_ID); + const char *error_string = error.AsCString(); + if (error_string == nullptr) + error_string = "launch failed"; + SetExitStatus(-1, error_string); } + } else { + EventSP event_sp; - if (error.Fail()) { - if (GetID() != LLDB_INVALID_PROCESS_ID) { - SetID(LLDB_INVALID_PROCESS_ID); - const char *error_string = error.AsCString(); - if (error_string == nullptr) - error_string = "launch failed"; - SetExitStatus(-1, error_string); - } - } else { - EventSP event_sp; - - // Now wait for the process to launch and return control to us, and then - // call DidLaunch: - StateType state = WaitForProcessStopPrivate(event_sp, seconds(10)); - - if (state == eStateInvalid || !event_sp) { - // We were able to launch the process, but we failed to catch the - // initial stop. - error.SetErrorString("failed to catch stop after launch"); - SetExitStatus(0, "failed to catch stop after launch"); - Destroy(false); - } else if (state == eStateStopped || state == eStateCrashed) { - DidLaunch(); - - DynamicLoader *dyld = GetDynamicLoader(); - if (dyld) - dyld->DidLaunch(); - - GetJITLoaders().DidLaunch(); - - SystemRuntime *system_runtime = GetSystemRuntime(); - if (system_runtime) - system_runtime->DidLaunch(); - - if (!m_os_up) - LoadOperatingSystemPlugin(false); - - // We successfully launched the process and stopped, now it the - // right time to set up signal filters before resuming. - UpdateAutomaticSignalFiltering(); - - // Note, the stop event was consumed above, but not handled. This - // was done to give DidLaunch a chance to run. The target is either - // stopped or crashed. Directly set the state. This is done to - // prevent a stop message with a bunch of spurious output on thread - // status, as well as not pop a ProcessIOHandler. - SetPublicState(state, false); - - if (PrivateStateThreadIsValid()) - ResumePrivateStateThread(); - else - StartPrivateStateThread(); + // Now wait for the process to launch and return control to us, and then + // call DidLaunch: + StateType state = WaitForProcessStopPrivate(event_sp, seconds(10)); + + if (state == eStateInvalid || !event_sp) { + // We were able to launch the process, but we failed to catch the + // initial stop. + error.SetErrorString("failed to catch stop after launch"); + SetExitStatus(0, "failed to catch stop after launch"); + Destroy(false); + } else if (state == eStateStopped || state == eStateCrashed) { + DidLaunch(); + + DynamicLoader *dyld = GetDynamicLoader(); + if (dyld) + dyld->DidLaunch(); + + GetJITLoaders().DidLaunch(); + + SystemRuntime *system_runtime = GetSystemRuntime(); + if (system_runtime) + system_runtime->DidLaunch(); + + if (!m_os_up) + LoadOperatingSystemPlugin(false); + + // We successfully launched the process and stopped, now it the + // right time to set up signal filters before resuming. + UpdateAutomaticSignalFiltering(); + + // Note, the stop event was consumed above, but not handled. This + // was done to give DidLaunch a chance to run. The target is either + // stopped or crashed. Directly set the state. This is done to + // prevent a stop message with a bunch of spurious output on thread + // status, as well as not pop a ProcessIOHandler. + // We are done with the launch hijack listener, and this stop should + // go to the public state listener: + RestoreProcessEvents(); + SetPublicState(state, false); + + if (PrivateStateThreadIsValid()) + ResumePrivateStateThread(); + else + StartPrivateStateThread(); - // Target was stopped at entry as was intended. Need to notify the - // listeners about it. - if (state == eStateStopped && - launch_info.GetFlags().Test(eLaunchFlagStopAtEntry)) - HandlePrivateEvent(event_sp); - } else if (state == eStateExited) { - // We exited while trying to launch somehow. Don't call DidLaunch - // as that's not likely to work, and return an invalid pid. + // Target was stopped at entry as was intended. Need to notify the + // listeners about it. + if (state == eStateStopped && + launch_info.GetFlags().Test(eLaunchFlagStopAtEntry)) HandlePrivateEvent(event_sp); - } + } else if (state == eStateExited) { + // We exited while trying to launch somehow. Don't call DidLaunch + // as that's not likely to work, and return an invalid pid. + HandlePrivateEvent(event_sp); } } } else { + std::string local_exec_file_path = exe_spec_to_use.GetPath(); error.SetErrorStringWithFormat("file doesn't exist: '%s'", - local_exec_file_path); + local_exec_file_path.c_str()); } return error; @@ -2625,12 +2614,16 @@ Status Process::LoadCore() { DynamicLoader *Process::GetDynamicLoader() { if (!m_dyld_up) - m_dyld_up.reset(DynamicLoader::FindPlugin(this, nullptr)); + m_dyld_up.reset(DynamicLoader::FindPlugin(this, "")); return m_dyld_up.get(); } DataExtractor Process::GetAuxvData() { return DataExtractor(); } +llvm::Expected<bool> Process::SaveCore(llvm::StringRef outfile) { + return false; +} + JITLoaderList &Process::GetJITLoaders() { if (!m_jit_loaders_up) { m_jit_loaders_up = std::make_unique<JITLoaderList>(); @@ -2916,13 +2909,11 @@ void Process::CompleteAttach() { dyld->DidAttach(); if (log) { ModuleSP exe_module_sp = GetTarget().GetExecutableModule(); - LLDB_LOGF(log, - "Process::%s after DynamicLoader::DidAttach(), target " - "executable is %s (using %s plugin)", - __FUNCTION__, - exe_module_sp ? exe_module_sp->GetFileSpec().GetPath().c_str() - : "<none>", - dyld->GetPluginName().AsCString("<unnamed>")); + LLDB_LOG(log, + "after DynamicLoader::DidAttach(), target " + "executable is {0} (using {1} plugin)", + exe_module_sp ? exe_module_sp->GetFileSpec() : FileSpec(), + dyld->GetPluginName()); } } @@ -2933,13 +2924,11 @@ void Process::CompleteAttach() { system_runtime->DidAttach(); if (log) { ModuleSP exe_module_sp = GetTarget().GetExecutableModule(); - LLDB_LOGF(log, - "Process::%s after SystemRuntime::DidAttach(), target " - "executable is %s (using %s plugin)", - __FUNCTION__, - exe_module_sp ? exe_module_sp->GetFileSpec().GetPath().c_str() - : "<none>", - system_runtime->GetPluginName().AsCString("<unnamed>")); + LLDB_LOG(log, + "after SystemRuntime::DidAttach(), target " + "executable is {0} (using {1} plugin)", + exe_module_sp ? exe_module_sp->GetFileSpec() : FileSpec(), + system_runtime->GetPluginName()); } } @@ -4310,8 +4299,8 @@ public: : IOHandler(process->GetTarget().GetDebugger(), IOHandler::Type::ProcessIO), m_process(process), - m_read_file(GetInputFD(), File::eOpenOptionRead, false), - m_write_file(write_fd, File::eOpenOptionWrite, false) { + m_read_file(GetInputFD(), File::eOpenOptionReadOnly, false), + m_write_file(write_fd, File::eOpenOptionWriteOnly, false) { m_pipe.CreateNew(false); } @@ -4328,11 +4317,11 @@ public: SetIsDone(false); const int read_fd = m_read_file.GetDescriptor(); - TerminalState terminal_state; - terminal_state.Save(read_fd, false); Terminal terminal(read_fd); - terminal.SetCanonical(false); - terminal.SetEcho(false); + TerminalState terminal_state(terminal, false); + // FIXME: error handling? + llvm::consumeError(terminal.SetCanonical(false)); + llvm::consumeError(terminal.SetEcho(false)); // FD_ZERO, FD_SET are not supported on windows #ifndef _WIN32 const int pipe_read_fd = m_pipe.GetReadFileDescriptor(); @@ -4376,7 +4365,6 @@ public: } m_is_running = false; #endif - terminal_state.Restore(); } void Cancel() override { @@ -4433,7 +4421,7 @@ public: protected: Process *m_process; NativeFile m_read_file; // Read from this file (usually actual STDIN for LLDB - NativeFile m_write_file; // Write to this file (usually the master pty for + NativeFile m_write_file; // Write to this file (usually the primary pty for // getting io to debuggee) Pipe m_pipe; std::atomic<bool> m_is_running{false}; @@ -4494,7 +4482,8 @@ void Process::SettingsInitialize() { Thread::SettingsInitialize(); } void Process::SettingsTerminate() { Thread::SettingsTerminate(); } namespace { -// RestorePlanState is used to record the "is private", "is master" and "okay +// RestorePlanState is used to record the "is private", "is controlling" and +// "okay // to discard" fields of the plan we are running, and reset it on Clean or on // destruction. It will only reset the state once, so you can call Clean and // then monkey with the state and it won't get reset on you again. @@ -4505,7 +4494,7 @@ public: : m_thread_plan_sp(thread_plan_sp), m_already_reset(false) { if (m_thread_plan_sp) { m_private = m_thread_plan_sp->GetPrivate(); - m_is_master = m_thread_plan_sp->IsMasterPlan(); + m_is_controlling = m_thread_plan_sp->IsControllingPlan(); m_okay_to_discard = m_thread_plan_sp->OkayToDiscard(); } } @@ -4516,7 +4505,7 @@ public: if (!m_already_reset && m_thread_plan_sp) { m_already_reset = true; m_thread_plan_sp->SetPrivate(m_private); - m_thread_plan_sp->SetIsMasterPlan(m_is_master); + m_thread_plan_sp->SetIsControllingPlan(m_is_controlling); m_thread_plan_sp->SetOkayToDiscard(m_okay_to_discard); } } @@ -4525,7 +4514,7 @@ private: lldb::ThreadPlanSP m_thread_plan_sp; bool m_already_reset; bool m_private; - bool m_is_master; + bool m_is_controlling; bool m_okay_to_discard; }; } // anonymous namespace @@ -4676,11 +4665,11 @@ Process::RunThreadPlan(ExecutionContext &exe_ctx, thread_plan_sp->SetPrivate(false); - // The plans run with RunThreadPlan also need to be terminal master plans or - // when they are done we will end up asking the plan above us whether we + // The plans run with RunThreadPlan also need to be terminal controlling plans + // or when they are done we will end up asking the plan above us whether we // should stop, which may give the wrong answer. - thread_plan_sp->SetIsMasterPlan(true); + thread_plan_sp->SetIsControllingPlan(true); thread_plan_sp->SetOkayToDiscard(false); // If we are running some utility expression for LLDB, we now have to mark @@ -5864,6 +5853,13 @@ Process::AdvanceAddressToNextBranchInstruction(Address default_stop_addr, return retval; } +Status Process::GetMemoryRegionInfo(lldb::addr_t load_addr, + MemoryRegionInfo &range_info) { + if (auto abi = GetABI()) + load_addr = abi->FixDataAddress(load_addr); + return DoGetMemoryRegionInfo(load_addr, range_info); +} + Status Process::GetMemoryRegions(lldb_private::MemoryRegionInfos ®ion_list) { @@ -5963,11 +5959,8 @@ void Process::MapSupportedStructuredDataPlugins( m_structured_data_plugin_map.insert( std::make_pair(type_name, plugin_sp)); names_to_remove.push_back(type_name); - LLDB_LOGF(log, - "Process::%s(): using plugin %s for type name " - "%s", - __FUNCTION__, plugin_sp->GetPluginName().GetCString(), - type_name.GetCString()); + LLDB_LOG(log, "using plugin {0} for type name {1}", + plugin_sp->GetPluginName(), type_name); } } @@ -6091,8 +6084,7 @@ llvm::Expected<const MemoryTagManager *> Process::GetMemoryTagManager() { if (!arch || !tag_manager) { return llvm::createStringError( llvm::inconvertibleErrorCode(), - "This architecture does not support memory tagging", - GetPluginName().GetCString()); + "This architecture does not support memory tagging"); } if (!SupportsMemoryTagging()) { diff --git a/contrib/llvm-project/lldb/source/Target/ProcessTrace.cpp b/contrib/llvm-project/lldb/source/Target/ProcessTrace.cpp index c878a2ac4eb9..41d5b01b61d8 100644 --- a/contrib/llvm-project/lldb/source/Target/ProcessTrace.cpp +++ b/contrib/llvm-project/lldb/source/Target/ProcessTrace.cpp @@ -19,12 +19,7 @@ using namespace lldb; using namespace lldb_private; -ConstString ProcessTrace::GetPluginNameStatic() { - static ConstString g_name("trace"); - return g_name; -} - -const char *ProcessTrace::GetPluginDescriptionStatic() { +llvm::StringRef ProcessTrace::GetPluginDescriptionStatic() { return "Trace process plug-in."; } @@ -57,10 +52,6 @@ ProcessTrace::~ProcessTrace() { Finalize(); } -ConstString ProcessTrace::GetPluginName() { return GetPluginNameStatic(); } - -uint32_t ProcessTrace::GetPluginVersion() { return 1; } - void ProcessTrace::DidAttach(ArchSpec &process_arch) { ListenerSP listener_sp( Listener::MakeListener("lldb.process_trace.did_attach_listener")); diff --git a/contrib/llvm-project/lldb/source/Target/RegisterContext.cpp b/contrib/llvm-project/lldb/source/Target/RegisterContext.cpp index bd50a9486ef3..7364660650e8 100644 --- a/contrib/llvm-project/lldb/source/Target/RegisterContext.cpp +++ b/contrib/llvm-project/lldb/source/Target/RegisterContext.cpp @@ -54,6 +54,17 @@ RegisterContext::GetRegisterInfoByName(llvm::StringRef reg_name, if (reg_name.empty()) return nullptr; + // Generic register names take precedence over specific register names. + // For example, on x86 we want "sp" to refer to the complete RSP/ESP register + // rather than the 16-bit SP pseudo-register. + uint32_t generic_reg = Args::StringToGenericRegister(reg_name); + if (generic_reg != LLDB_INVALID_REGNUM) { + const RegisterInfo *reg_info = + GetRegisterInfo(eRegisterKindGeneric, generic_reg); + if (reg_info) + return reg_info; + } + const uint32_t num_registers = GetRegisterCount(); for (uint32_t reg = start_idx; reg < num_registers; ++reg) { const RegisterInfo *reg_info = GetRegisterInfoAtIndex(reg); @@ -62,45 +73,8 @@ RegisterContext::GetRegisterInfoByName(llvm::StringRef reg_name, reg_name.equals_insensitive(reg_info->alt_name)) return reg_info; } - return nullptr; -} -uint32_t -RegisterContext::UpdateDynamicRegisterSize(const lldb_private::ArchSpec &arch, - RegisterInfo *reg_info) { - ExecutionContext exe_ctx(CalculateThread()); - - // In MIPS, the floating point registers size is depends on FR bit of SR - // register. if SR.FR == 1 then all floating point registers are 64 bits. - // else they are all 32 bits. - - int expr_result; - uint32_t addr_size = arch.GetAddressByteSize(); - const uint8_t *dwarf_opcode_ptr = reg_info->dynamic_size_dwarf_expr_bytes; - const size_t dwarf_opcode_len = reg_info->dynamic_size_dwarf_len; - - DataExtractor dwarf_data(dwarf_opcode_ptr, dwarf_opcode_len, - arch.GetByteOrder(), addr_size); - ModuleSP opcode_ctx; - DWARFExpression dwarf_expr(opcode_ctx, dwarf_data, nullptr); - Value result; - Status error; - if (dwarf_expr.Evaluate(&exe_ctx, this, opcode_ctx, dwarf_data, nullptr, - eRegisterKindDWARF, nullptr, nullptr, result, - &error)) { - expr_result = result.GetScalar().SInt(-1); - switch (expr_result) { - case 0: - return 4; - case 1: - return 8; - default: - return reg_info->byte_size; - } - } else { - printf("Error executing DwarfExpression::Evaluate %s\n", error.AsCString()); - return reg_info->byte_size; - } + return nullptr; } const RegisterInfo *RegisterContext::GetRegisterInfo(lldb::RegisterKind kind, diff --git a/contrib/llvm-project/lldb/source/Target/RegisterContextUnwind.cpp b/contrib/llvm-project/lldb/source/Target/RegisterContextUnwind.cpp index 1ce21e6306e0..96b69640a3a3 100644 --- a/contrib/llvm-project/lldb/source/Target/RegisterContextUnwind.cpp +++ b/contrib/llvm-project/lldb/source/Target/RegisterContextUnwind.cpp @@ -893,13 +893,22 @@ UnwindPlanSP RegisterContextUnwind::GetFullUnwindPlanForFrame() { return arch_default_unwind_plan_sp; } - // If we're in _sigtramp(), unwinding past this frame requires special - // knowledge. On Mac OS X this knowledge is properly encoded in the eh_frame - // section, so prefer that if available. On other platforms we may need to - // provide a platform-specific UnwindPlan which encodes the details of how to - // unwind out of sigtramp. if (m_frame_type == eTrapHandlerFrame && process) { m_fast_unwind_plan_sp.reset(); + + // On some platforms the unwind information for signal handlers is not + // present or correct. Give the platform plugins a chance to provide + // substitute plan. Otherwise, use eh_frame. + if (m_sym_ctx_valid) { + lldb::PlatformSP platform = process->GetTarget().GetPlatform(); + unwind_plan_sp = platform->GetTrapHandlerUnwindPlan( + process->GetTarget().GetArchitecture().GetTriple(), + GetSymbolOrFunctionName(m_sym_ctx)); + + if (unwind_plan_sp) + return unwind_plan_sp; + } + unwind_plan_sp = func_unwinders_sp->GetEHFrameUnwindPlan(process->GetTarget()); if (!unwind_plan_sp) diff --git a/contrib/llvm-project/lldb/source/Target/RemoteAwarePlatform.cpp b/contrib/llvm-project/lldb/source/Target/RemoteAwarePlatform.cpp index b0c43ffa839e..eb39fc6db304 100644 --- a/contrib/llvm-project/lldb/source/Target/RemoteAwarePlatform.cpp +++ b/contrib/llvm-project/lldb/source/Target/RemoteAwarePlatform.cpp @@ -72,8 +72,7 @@ Status RemoteAwarePlatform::ResolveExecutable( } else { if (m_remote_platform_sp) { return GetCachedExecutable(resolved_module_spec, exe_module_sp, - module_search_paths_ptr, - *m_remote_platform_sp); + module_search_paths_ptr); } // We may connect to a process and use the provided executable (Don't use @@ -154,10 +153,10 @@ Status RemoteAwarePlatform::ResolveExecutable( if (error.Fail() || !exe_module_sp) { if (FileSystem::Instance().Readable( resolved_module_spec.GetFileSpec())) { - error.SetErrorStringWithFormat( - "'%s' doesn't contain any '%s' platform architectures: %s", - resolved_module_spec.GetFileSpec().GetPath().c_str(), - GetPluginName().GetCString(), arch_names.GetData()); + error.SetErrorStringWithFormatv( + "'{0}' doesn't contain any '{1}' platform architectures: {2}", + resolved_module_spec.GetFileSpec(), GetPluginName(), + arch_names.GetData()); } else { error.SetErrorStringWithFormat( "'%s' is not readable", @@ -332,18 +331,16 @@ bool RemoteAwarePlatform::GetRemoteOSVersion() { return false; } -bool RemoteAwarePlatform::GetRemoteOSBuildString(std::string &s) { +llvm::Optional<std::string> RemoteAwarePlatform::GetRemoteOSBuildString() { if (m_remote_platform_sp) - return m_remote_platform_sp->GetRemoteOSBuildString(s); - s.clear(); - return false; + return m_remote_platform_sp->GetRemoteOSBuildString(); + return llvm::None; } -bool RemoteAwarePlatform::GetRemoteOSKernelDescription(std::string &s) { +llvm::Optional<std::string> RemoteAwarePlatform::GetRemoteOSKernelDescription() { if (m_remote_platform_sp) - return m_remote_platform_sp->GetRemoteOSKernelDescription(s); - s.clear(); - return false; + return m_remote_platform_sp->GetRemoteOSKernelDescription(); + return llvm::None; } ArchSpec RemoteAwarePlatform::GetRemoteSystemArchitecture() { diff --git a/contrib/llvm-project/lldb/source/Target/Statistics.cpp b/contrib/llvm-project/lldb/source/Target/Statistics.cpp new file mode 100644 index 000000000000..1b205c533519 --- /dev/null +++ b/contrib/llvm-project/lldb/source/Target/Statistics.cpp @@ -0,0 +1,196 @@ +//===-- Statistics.cpp ----------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "lldb/Target/Statistics.h" + +#include "lldb/Core/Debugger.h" +#include "lldb/Core/Module.h" +#include "lldb/Symbol/SymbolFile.h" +#include "lldb/Target/Process.h" +#include "lldb/Target/Target.h" +#include "lldb/Target/UnixSignals.h" + +using namespace lldb; +using namespace lldb_private; +using namespace llvm; + +static void EmplaceSafeString(llvm::json::Object &obj, llvm::StringRef key, + const std::string &str) { + if (str.empty()) + return; + if (LLVM_LIKELY(llvm::json::isUTF8(str))) + obj.try_emplace(key, str); + else + obj.try_emplace(key, llvm::json::fixUTF8(str)); +} + +json::Value StatsSuccessFail::ToJSON() const { + return json::Object{{"successes", successes}, {"failures", failures}}; +} + +static double elapsed(const StatsTimepoint &start, const StatsTimepoint &end) { + StatsDuration elapsed = end.time_since_epoch() - start.time_since_epoch(); + return elapsed.count(); +} + +void TargetStats::CollectStats(Target &target) { + m_module_identifiers.clear(); + for (ModuleSP module_sp : target.GetImages().Modules()) + m_module_identifiers.emplace_back((intptr_t)module_sp.get()); +} + +json::Value ModuleStats::ToJSON() const { + json::Object module; + EmplaceSafeString(module, "path", path); + EmplaceSafeString(module, "uuid", uuid); + EmplaceSafeString(module, "triple", triple); + module.try_emplace("identifier", identifier); + module.try_emplace("symbolTableParseTime", symtab_parse_time); + module.try_emplace("symbolTableIndexTime", symtab_index_time); + module.try_emplace("debugInfoParseTime", debug_parse_time); + module.try_emplace("debugInfoIndexTime", debug_index_time); + module.try_emplace("debugInfoByteSize", (int64_t)debug_info_size); + return module; +} + +json::Value TargetStats::ToJSON(Target &target) { + CollectStats(target); + + json::Array json_module_uuid_array; + for (auto module_identifier : m_module_identifiers) + json_module_uuid_array.emplace_back(module_identifier); + + json::Object target_metrics_json{ + {m_expr_eval.name, m_expr_eval.ToJSON()}, + {m_frame_var.name, m_frame_var.ToJSON()}, + {"moduleIdentifiers", std::move(json_module_uuid_array)}}; + + if (m_launch_or_attach_time && m_first_private_stop_time) { + double elapsed_time = + elapsed(*m_launch_or_attach_time, *m_first_private_stop_time); + target_metrics_json.try_emplace("launchOrAttachTime", elapsed_time); + } + if (m_launch_or_attach_time && m_first_public_stop_time) { + double elapsed_time = + elapsed(*m_launch_or_attach_time, *m_first_public_stop_time); + target_metrics_json.try_emplace("firstStopTime", elapsed_time); + } + target_metrics_json.try_emplace("targetCreateTime", m_create_time.count()); + + json::Array breakpoints_array; + double totalBreakpointResolveTime = 0.0; + // Rport both the normal breakpoint list and the internal breakpoint list. + for (int i = 0; i < 2; ++i) { + BreakpointList &breakpoints = target.GetBreakpointList(i == 1); + std::unique_lock<std::recursive_mutex> lock; + breakpoints.GetListMutex(lock); + size_t num_breakpoints = breakpoints.GetSize(); + for (size_t i = 0; i < num_breakpoints; i++) { + Breakpoint *bp = breakpoints.GetBreakpointAtIndex(i).get(); + breakpoints_array.push_back(bp->GetStatistics()); + totalBreakpointResolveTime += bp->GetResolveTime().count(); + } + } + + ProcessSP process_sp = target.GetProcessSP(); + if (process_sp) { + UnixSignalsSP unix_signals_sp = process_sp->GetUnixSignals(); + if (unix_signals_sp) + target_metrics_json.try_emplace("signals", + unix_signals_sp->GetHitCountStatistics()); + uint32_t stop_id = process_sp->GetStopID(); + target_metrics_json.try_emplace("stopCount", stop_id); + } + target_metrics_json.try_emplace("breakpoints", std::move(breakpoints_array)); + target_metrics_json.try_emplace("totalBreakpointResolveTime", + totalBreakpointResolveTime); + + return target_metrics_json; +} + +void TargetStats::SetLaunchOrAttachTime() { + m_launch_or_attach_time = StatsClock::now(); + m_first_private_stop_time = llvm::None; +} + +void TargetStats::SetFirstPrivateStopTime() { + // Launching and attaching has many paths depending on if synchronous mode + // was used or if we are stopping at the entry point or not. Only set the + // first stop time if it hasn't already been set. + if (!m_first_private_stop_time) + m_first_private_stop_time = StatsClock::now(); +} + +void TargetStats::SetFirstPublicStopTime() { + // Launching and attaching has many paths depending on if synchronous mode + // was used or if we are stopping at the entry point or not. Only set the + // first stop time if it hasn't already been set. + if (!m_first_public_stop_time) + m_first_public_stop_time = StatsClock::now(); +} + +bool DebuggerStats::g_collecting_stats = false; + +llvm::json::Value DebuggerStats::ReportStatistics(Debugger &debugger, + Target *target) { + json::Array json_targets; + json::Array json_modules; + double symtab_parse_time = 0.0; + double symtab_index_time = 0.0; + double debug_parse_time = 0.0; + double debug_index_time = 0.0; + uint64_t debug_info_size = 0; + if (target) { + json_targets.emplace_back(target->ReportStatistics()); + } else { + for (const auto &target : debugger.GetTargetList().Targets()) + json_targets.emplace_back(target->ReportStatistics()); + } + std::vector<ModuleStats> modules; + std::lock_guard<std::recursive_mutex> guard( + Module::GetAllocationModuleCollectionMutex()); + const size_t num_modules = Module::GetNumberAllocatedModules(); + for (size_t image_idx = 0; image_idx < num_modules; ++image_idx) { + Module *module = Module::GetAllocatedModuleAtIndex(image_idx); + ModuleStats module_stat; + module_stat.identifier = (intptr_t)module; + module_stat.path = module->GetFileSpec().GetPath(); + if (ConstString object_name = module->GetObjectName()) { + module_stat.path.append(1, '('); + module_stat.path.append(object_name.GetStringRef().str()); + module_stat.path.append(1, ')'); + } + module_stat.uuid = module->GetUUID().GetAsString(); + module_stat.triple = module->GetArchitecture().GetTriple().str(); + module_stat.symtab_parse_time = module->GetSymtabParseTime().count(); + module_stat.symtab_index_time = module->GetSymtabIndexTime().count(); + SymbolFile *sym_file = module->GetSymbolFile(); + if (sym_file) { + module_stat.debug_index_time = sym_file->GetDebugInfoIndexTime().count(); + module_stat.debug_parse_time = sym_file->GetDebugInfoParseTime().count(); + module_stat.debug_info_size = sym_file->GetDebugInfoSize(); + } + symtab_parse_time += module_stat.symtab_parse_time; + symtab_index_time += module_stat.symtab_index_time; + debug_parse_time += module_stat.debug_parse_time; + debug_index_time += module_stat.debug_index_time; + debug_info_size += module_stat.debug_info_size; + json_modules.emplace_back(module_stat.ToJSON()); + } + + json::Object global_stats{ + {"targets", std::move(json_targets)}, + {"modules", std::move(json_modules)}, + {"totalSymbolTableParseTime", symtab_parse_time}, + {"totalSymbolTableIndexTime", symtab_index_time}, + {"totalDebugInfoParseTime", debug_parse_time}, + {"totalDebugInfoIndexTime", debug_index_time}, + {"totalDebugInfoByteSize", debug_info_size}, + }; + return std::move(global_stats); +} diff --git a/contrib/llvm-project/lldb/source/Target/StopInfo.cpp b/contrib/llvm-project/lldb/source/Target/StopInfo.cpp index aeb97f1919eb..1de281b1761f 100644 --- a/contrib/llvm-project/lldb/source/Target/StopInfo.cpp +++ b/contrib/llvm-project/lldb/source/Target/StopInfo.cpp @@ -307,7 +307,7 @@ protected: // There's one other complication here. We may have run an async // breakpoint callback that said we should stop. We only want to - // override that if another breakpoint action says we shouldn't + // override that if another breakpoint action says we shouldn't // stop. If nobody else has an opinion, then we should stop if the // async callback says we should. An example of this is the async // shared library load notification breakpoint and the setting @@ -425,7 +425,7 @@ protected: } internal_breakpoint = bp_loc_sp->GetBreakpoint().IsInternal(); - + // First run the precondition, but since the precondition is per // breakpoint, only run it once per breakpoint. std::pair<std::unordered_set<break_id_t>::iterator, bool> result = @@ -535,7 +535,7 @@ protected: else actually_said_continue = true; } - + // If we are going to stop for this breakpoint, then remove the // breakpoint. if (callback_says_stop && bp_loc_sp && @@ -579,7 +579,7 @@ protected: // Override should_stop decision when we have completed step plan // additionally to the breakpoint m_should_stop = true; - + // We know we're stopping for a completed plan and we don't want to // show the breakpoint stop, so compute the public stop info immediately // here. @@ -615,7 +615,7 @@ public: // performing watchpoint actions. class WatchpointSentry { public: - WatchpointSentry(ProcessSP p_sp, WatchpointSP w_sp) : process_sp(p_sp), + WatchpointSentry(ProcessSP p_sp, WatchpointSP w_sp) : process_sp(p_sp), watchpoint_sp(w_sp) { if (process_sp && watchpoint_sp) { const bool notify = false; @@ -624,7 +624,7 @@ public: process_sp->AddPreResumeAction(SentryPreResumeAction, this); } } - + void DoReenable() { if (process_sp && watchpoint_sp) { bool was_disabled = watchpoint_sp->IsDisabledDuringEphemeralMode(); @@ -637,13 +637,13 @@ public: } } } - + ~WatchpointSentry() { DoReenable(); if (process_sp) process_sp->ClearPreResumeAction(SentryPreResumeAction, this); } - + static bool SentryPreResumeAction(void *sentry_void) { WatchpointSentry *sentry = (WatchpointSentry *) sentry_void; sentry->DoReenable(); @@ -724,14 +724,14 @@ protected: // course of this code. Also by default we're going to stop, so set that // here. m_should_stop = true; - + ThreadSP thread_sp(m_thread_wp.lock()); if (thread_sp) { WatchpointSP wp_sp( thread_sp->CalculateTarget()->GetWatchpointList().FindByID( - GetValue())); + GetValue())); if (wp_sp) { ExecutionContext exe_ctx(thread_sp->GetStackFrameAtIndex(0)); ProcessSP process_sp = exe_ctx.GetProcessSP(); @@ -764,7 +764,7 @@ protected: true, // stop_other_threads new_plan_status)); if (new_plan_sp && new_plan_status.Success()) { - new_plan_sp->SetIsMasterPlan(true); + new_plan_sp->SetIsControllingPlan(true); new_plan_sp->SetOkayToDiscard(false); new_plan_sp->SetPrivate(true); } @@ -889,12 +889,12 @@ protected: bool old_async = debugger.GetAsyncExecution(); debugger.SetAsyncExecution(true); - + StoppointCallbackContext context(event_ptr, exe_ctx, false); bool stop_requested = wp_sp->InvokeCallback(&context); - + debugger.SetAsyncExecution(old_async); - + // Also make sure that the callback hasn't continued the target. If // it did, when we'll set m_should_stop to false and get out of here. if (HasTargetRunSinceMe()) @@ -1154,6 +1154,103 @@ protected: bool m_performed_action; }; +// StopInfoFork + +class StopInfoFork : public StopInfo { +public: + StopInfoFork(Thread &thread, lldb::pid_t child_pid, lldb::tid_t child_tid) + : StopInfo(thread, child_pid), m_performed_action(false), + m_child_pid(child_pid), m_child_tid(child_tid) {} + + ~StopInfoFork() override = default; + + bool ShouldStop(Event *event_ptr) override { return false; } + + StopReason GetStopReason() const override { return eStopReasonFork; } + + const char *GetDescription() override { return "fork"; } + +protected: + void PerformAction(Event *event_ptr) override { + // Only perform the action once + if (m_performed_action) + return; + m_performed_action = true; + ThreadSP thread_sp(m_thread_wp.lock()); + if (thread_sp) + thread_sp->GetProcess()->DidFork(m_child_pid, m_child_tid); + } + + bool m_performed_action; + +private: + lldb::pid_t m_child_pid; + lldb::tid_t m_child_tid; +}; + +// StopInfoVFork + +class StopInfoVFork : public StopInfo { +public: + StopInfoVFork(Thread &thread, lldb::pid_t child_pid, lldb::tid_t child_tid) + : StopInfo(thread, child_pid), m_performed_action(false), + m_child_pid(child_pid), m_child_tid(child_tid) {} + + ~StopInfoVFork() override = default; + + bool ShouldStop(Event *event_ptr) override { return false; } + + StopReason GetStopReason() const override { return eStopReasonVFork; } + + const char *GetDescription() override { return "vfork"; } + +protected: + void PerformAction(Event *event_ptr) override { + // Only perform the action once + if (m_performed_action) + return; + m_performed_action = true; + ThreadSP thread_sp(m_thread_wp.lock()); + if (thread_sp) + thread_sp->GetProcess()->DidVFork(m_child_pid, m_child_tid); + } + + bool m_performed_action; + +private: + lldb::pid_t m_child_pid; + lldb::tid_t m_child_tid; +}; + +// StopInfoVForkDone + +class StopInfoVForkDone : public StopInfo { +public: + StopInfoVForkDone(Thread &thread) + : StopInfo(thread, 0), m_performed_action(false) {} + + ~StopInfoVForkDone() override = default; + + bool ShouldStop(Event *event_ptr) override { return false; } + + StopReason GetStopReason() const override { return eStopReasonVForkDone; } + + const char *GetDescription() override { return "vforkdone"; } + +protected: + void PerformAction(Event *event_ptr) override { + // Only perform the action once + if (m_performed_action) + return; + m_performed_action = true; + ThreadSP thread_sp(m_thread_wp.lock()); + if (thread_sp) + thread_sp->GetProcess()->DidVForkDone(); + } + + bool m_performed_action; +}; + } // namespace lldb_private StopInfoSP StopInfo::CreateStopReasonWithBreakpointSiteID(Thread &thread, @@ -1175,6 +1272,7 @@ StopInfo::CreateStopReasonWithWatchpointID(Thread &thread, break_id_t watch_id, StopInfoSP StopInfo::CreateStopReasonWithSignal(Thread &thread, int signo, const char *description) { + thread.GetProcess()->GetUnixSignals()->IncrementSignalHitCount(signo); return StopInfoSP(new StopInfoUnixSignal(thread, signo, description)); } @@ -1203,6 +1301,23 @@ StopInfoSP StopInfo::CreateStopReasonWithExec(Thread &thread) { return StopInfoSP(new StopInfoExec(thread)); } +StopInfoSP StopInfo::CreateStopReasonFork(Thread &thread, + lldb::pid_t child_pid, + lldb::tid_t child_tid) { + return StopInfoSP(new StopInfoFork(thread, child_pid, child_tid)); +} + + +StopInfoSP StopInfo::CreateStopReasonVFork(Thread &thread, + lldb::pid_t child_pid, + lldb::tid_t child_tid) { + return StopInfoSP(new StopInfoVFork(thread, child_pid, child_tid)); +} + +StopInfoSP StopInfo::CreateStopReasonVForkDone(Thread &thread) { + return StopInfoSP(new StopInfoVForkDone(thread)); +} + ValueObjectSP StopInfo::GetReturnValueObject(StopInfoSP &stop_info_sp) { if (stop_info_sp && stop_info_sp->GetStopReason() == eStopReasonPlanComplete) { diff --git a/contrib/llvm-project/lldb/source/Target/Target.cpp b/contrib/llvm-project/lldb/source/Target/Target.cpp index 1f8e8c54fa9e..28575b50cf96 100644 --- a/contrib/llvm-project/lldb/source/Target/Target.cpp +++ b/contrib/llvm-project/lldb/source/Target/Target.cpp @@ -60,6 +60,7 @@ #include "lldb/Utility/Timer.h" #include "llvm/ADT/ScopeExit.h" +#include "llvm/ADT/SetVector.h" #include <memory> #include <mutex> @@ -95,14 +96,10 @@ Target::Target(Debugger &debugger, const ArchSpec &target_arch, m_watchpoint_list(), m_process_sp(), m_search_filter_sp(), m_image_search_paths(ImageSearchPathsChanged, this), m_source_manager_up(), m_stop_hooks(), m_stop_hook_next_id(0), - m_latest_stop_hook_id(0), - m_valid(true), m_suppress_stop_hooks(false), + m_latest_stop_hook_id(0), m_valid(true), m_suppress_stop_hooks(false), m_is_dummy_target(is_dummy_target), m_frame_recognizer_manager_up( - std::make_unique<StackFrameRecognizerManager>()), - m_stats_storage(static_cast<int>(StatisticKind::StatisticMax)) - -{ + std::make_unique<StackFrameRecognizerManager>()) { SetEventName(eBroadcastBitBreakpointChanged, "breakpoint-changed"); SetEventName(eBroadcastBitModulesLoaded, "modules-loaded"); SetEventName(eBroadcastBitModulesUnloaded, "modules-unloaded"); @@ -1022,7 +1019,7 @@ Status Target::SerializeBreakpointsToFile(const FileSpec &file, } StreamFile out_file(path.c_str(), - File::eOpenOptionTruncate | File::eOpenOptionWrite | + File::eOpenOptionTruncate | File::eOpenOptionWriteOnly | File::eOpenOptionCanCreate | File::eOpenOptionCloseOnExec, lldb::eFilePermissionsFileDefault); @@ -1400,6 +1397,7 @@ void Target::SetExecutableModule(ModuleSP &executable_sp, ClearModules(false); if (executable_sp) { + ElapsedTime elapsed(m_stats.GetCreateTime()); LLDB_SCOPED_TIMERF("Target::SetExecutableModule (executable = '%s')", executable_sp->GetFileSpec().GetPath().c_str()); @@ -1906,6 +1904,68 @@ size_t Target::ReadCStringFromMemory(const Address &addr, char *dst, return total_cstr_len; } +addr_t Target::GetReasonableReadSize(const Address &addr) { + addr_t load_addr = addr.GetLoadAddress(this); + if (load_addr != LLDB_INVALID_ADDRESS && m_process_sp) { + // Avoid crossing cache line boundaries. + addr_t cache_line_size = m_process_sp->GetMemoryCacheLineSize(); + return cache_line_size - (load_addr % cache_line_size); + } + + // The read is going to go to the file cache, so we can just pick a largish + // value. + return 0x1000; +} + +size_t Target::ReadStringFromMemory(const Address &addr, char *dst, + size_t max_bytes, Status &error, + size_t type_width, bool force_live_memory) { + if (!dst || !max_bytes || !type_width || max_bytes < type_width) + return 0; + + size_t total_bytes_read = 0; + + // Ensure a null terminator independent of the number of bytes that is + // read. + memset(dst, 0, max_bytes); + size_t bytes_left = max_bytes - type_width; + + const char terminator[4] = {'\0', '\0', '\0', '\0'}; + assert(sizeof(terminator) >= type_width && "Attempting to validate a " + "string with more than 4 bytes " + "per character!"); + + Address address = addr; + char *curr_dst = dst; + + error.Clear(); + while (bytes_left > 0 && error.Success()) { + addr_t bytes_to_read = + std::min<addr_t>(bytes_left, GetReasonableReadSize(address)); + size_t bytes_read = + ReadMemory(address, curr_dst, bytes_to_read, error, force_live_memory); + + if (bytes_read == 0) + break; + + // Search for a null terminator of correct size and alignment in + // bytes_read + size_t aligned_start = total_bytes_read - total_bytes_read % type_width; + for (size_t i = aligned_start; + i + type_width <= total_bytes_read + bytes_read; i += type_width) + if (::memcmp(&dst[i], terminator, type_width) == 0) { + error.Clear(); + return i; + } + + total_bytes_read += bytes_read; + curr_dst += bytes_read; + address.Slide(bytes_read); + bytes_left -= bytes_read; + } + return total_bytes_read; +} + size_t Target::ReadScalarIntegerFromMemory(const Address &addr, uint32_t byte_size, bool is_signed, Scalar &scalar, Status &error, @@ -2231,7 +2291,10 @@ std::vector<TypeSystem *> Target::GetScratchTypeSystems(bool create_on_demand) { if (!m_valid) return {}; - std::vector<TypeSystem *> scratch_type_systems; + // Some TypeSystem instances are associated with several LanguageTypes so + // they will show up several times in the loop below. The SetVector filters + // out all duplicates as they serve no use for the caller. + llvm::SetVector<TypeSystem *> scratch_type_systems; LanguageSet languages_for_expressions = Language::GetLanguagesSupportingTypeSystemsForExpressions(); @@ -2247,10 +2310,10 @@ std::vector<TypeSystem *> Target::GetScratchTypeSystems(bool create_on_demand) { "system available", Language::GetNameForLanguageType(language)); else - scratch_type_systems.emplace_back(&type_system_or_err.get()); + scratch_type_systems.insert(&type_system_or_err.get()); } - return scratch_type_systems; + return scratch_type_systems.takeVector(); } PersistentExpressionState * @@ -2345,35 +2408,22 @@ void Target::SettingsInitialize() { Process::SettingsInitialize(); } void Target::SettingsTerminate() { Process::SettingsTerminate(); } FileSpecList Target::GetDefaultExecutableSearchPaths() { - TargetPropertiesSP properties_sp(Target::GetGlobalProperties()); - if (properties_sp) - return properties_sp->GetExecutableSearchPaths(); - return FileSpecList(); + return Target::GetGlobalProperties().GetExecutableSearchPaths(); } FileSpecList Target::GetDefaultDebugFileSearchPaths() { - TargetPropertiesSP properties_sp(Target::GetGlobalProperties()); - if (properties_sp) - return properties_sp->GetDebugFileSearchPaths(); - return FileSpecList(); + return Target::GetGlobalProperties().GetDebugFileSearchPaths(); } ArchSpec Target::GetDefaultArchitecture() { - TargetPropertiesSP properties_sp(Target::GetGlobalProperties()); - if (properties_sp) - return properties_sp->GetDefaultArchitecture(); - return ArchSpec(); + return Target::GetGlobalProperties().GetDefaultArchitecture(); } void Target::SetDefaultArchitecture(const ArchSpec &arch) { - TargetPropertiesSP properties_sp(Target::GetGlobalProperties()); - if (properties_sp) { - LLDB_LOG(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_TARGET), - "Target::SetDefaultArchitecture setting target's " - "default architecture to {0} ({1})", - arch.GetArchitectureName(), arch.GetTriple().getTriple()); - return properties_sp->SetDefaultArchitecture(arch); - } + LLDB_LOG(GetLogIfAllCategoriesSet(LIBLLDB_LOG_TARGET), + "setting target's default architecture to {0} ({1})", + arch.GetArchitectureName(), arch.GetTriple().getTriple()); + Target::GetGlobalProperties().SetDefaultArchitecture(arch); } Target *Target::GetTargetFromContexts(const ExecutionContext *exe_ctx_ptr, @@ -2399,8 +2449,10 @@ ExpressionResults Target::EvaluateExpression( ExpressionResults execution_results = eExpressionSetupError; - if (expr.empty()) + if (expr.empty()) { + m_stats.GetExpressionStats().NotifyFailure(); return execution_results; + } // We shouldn't run stop hooks in expressions. bool old_suppress_value = m_suppress_stop_hooks; @@ -2445,6 +2497,10 @@ ExpressionResults Target::EvaluateExpression( fixed_expression, ctx_obj); } + if (execution_results == eExpressionCompleted) + m_stats.GetExpressionStats().NotifySuccess(); + else + m_stats.GetExpressionStats().NotifyFailure(); return execution_results; } @@ -2768,12 +2824,12 @@ bool Target::RunStopHooks() { return false; } -const TargetPropertiesSP &Target::GetGlobalProperties() { +TargetProperties &Target::GetGlobalProperties() { // NOTE: intentional leak so we don't crash if global destructor chain gets // called as other threads still use the result of this function - static TargetPropertiesSP *g_settings_sp_ptr = - new TargetPropertiesSP(new TargetProperties(nullptr)); - return *g_settings_sp_ptr; + static TargetProperties *g_settings_ptr = + new TargetProperties(nullptr); + return *g_settings_ptr; } Status Target::Install(ProcessLaunchInfo *launch_info) { @@ -2908,6 +2964,7 @@ bool Target::SetSectionUnloaded(const lldb::SectionSP §ion_sp, void Target::ClearAllLoadedSections() { m_section_load_history.Clear(); } Status Target::Launch(ProcessLaunchInfo &launch_info, Stream *stream) { + m_stats.SetLaunchOrAttachTime(); Status error; Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_TARGET)); @@ -2936,17 +2993,9 @@ Status Target::Launch(ProcessLaunchInfo &launch_info, Stream *stream) { launch_info.GetFlags().Set(eLaunchFlagDebug); if (launch_info.IsScriptedProcess()) { - TargetPropertiesSP properties_sp = GetGlobalProperties(); - - if (!properties_sp) { - LLDB_LOGF(log, "Target::%s Couldn't fetch target global properties.", - __FUNCTION__); - return error; - } - // Only copy scripted process launch options. - ProcessLaunchInfo &default_launch_info = - const_cast<ProcessLaunchInfo &>(properties_sp->GetProcessLaunchInfo()); + ProcessLaunchInfo &default_launch_info = const_cast<ProcessLaunchInfo &>( + GetGlobalProperties().GetProcessLaunchInfo()); default_launch_info.SetProcessPluginName("ScriptedProcess"); default_launch_info.SetScriptedProcessClassName( @@ -2993,7 +3042,7 @@ Status Target::Launch(ProcessLaunchInfo &launch_info, Stream *stream) { DeleteCurrentProcess(); m_process_sp = - GetPlatform()->DebugProcess(launch_info, debugger, this, error); + GetPlatform()->DebugProcess(launch_info, debugger, *this, error); } else { LLDB_LOGF(log, @@ -3119,6 +3168,7 @@ llvm::Expected<TraceSP> Target::GetTraceOrCreate() { } Status Target::Attach(ProcessAttachInfo &attach_info, Stream *stream) { + m_stats.SetLaunchOrAttachTime(); auto state = eStateInvalid; auto process_sp = GetProcessSP(); if (process_sp) { @@ -3731,7 +3781,7 @@ TargetProperties::TargetProperties(Target *target) : Properties(), m_launch_info(), m_target(target) { if (target) { m_collection_sp = - OptionValueProperties::CreateLocalCopy(*Target::GetGlobalProperties()); + OptionValueProperties::CreateLocalCopy(Target::GetGlobalProperties()); // Set callbacks to update launch_info whenever "settins set" updated any // of these properties @@ -3781,7 +3831,7 @@ TargetProperties::TargetProperties(Target *target) true, m_experimental_properties_up->GetValueProperties()); m_collection_sp->AppendProperty( ConstString("process"), ConstString("Settings specific to processes."), - true, Process::GetGlobalProperties()->GetValueProperties()); + true, Process::GetGlobalProperties().GetValueProperties()); } } @@ -3985,6 +4035,45 @@ Environment TargetProperties::GetEnvironment() const { return ComputeEnvironment(); } +Environment TargetProperties::GetInheritedEnvironment() const { + Environment environment; + + if (m_target == nullptr) + return environment; + + if (!m_collection_sp->GetPropertyAtIndexAsBoolean( + nullptr, ePropertyInheritEnv, + g_target_properties[ePropertyInheritEnv].default_uint_value != 0)) + return environment; + + PlatformSP platform_sp = m_target->GetPlatform(); + if (platform_sp == nullptr) + return environment; + + Environment platform_environment = platform_sp->GetEnvironment(); + for (const auto &KV : platform_environment) + environment[KV.first()] = KV.second; + + Args property_unset_environment; + m_collection_sp->GetPropertyAtIndexAsArgs(nullptr, ePropertyUnsetEnvVars, + property_unset_environment); + for (const auto &var : property_unset_environment) + environment.erase(var.ref()); + + return environment; +} + +Environment TargetProperties::GetTargetEnvironment() const { + Args property_environment; + m_collection_sp->GetPropertyAtIndexAsArgs(nullptr, ePropertyEnvVars, + property_environment); + Environment environment; + for (const auto &KV : Environment(property_environment)) + environment[KV.first()] = KV.second; + + return environment; +} + void TargetProperties::SetEnvironment(Environment env) { // TODO: Get rid of the Args intermediate step const uint32_t idx = ePropertyEnvVars; @@ -4249,16 +4338,6 @@ void TargetProperties::SetDisplayRecognizedArguments(bool b) { m_collection_sp->SetPropertyAtIndexAsBoolean(nullptr, idx, b); } -bool TargetProperties::GetNonStopModeEnabled() const { - const uint32_t idx = ePropertyNonStopModeEnabled; - return m_collection_sp->GetPropertyAtIndexAsBoolean(nullptr, idx, false); -} - -void TargetProperties::SetNonStopModeEnabled(bool b) { - const uint32_t idx = ePropertyNonStopModeEnabled; - m_collection_sp->SetPropertyAtIndexAsBoolean(nullptr, idx, b); -} - const ProcessLaunchInfo &TargetProperties::GetProcessLaunchInfo() const { return m_launch_info; } @@ -4435,3 +4514,6 @@ std::recursive_mutex &Target::GetAPIMutex() { else return m_mutex; } + +/// Get metrics associated with this target in JSON format. +llvm::json::Value Target::ReportStatistics() { return m_stats.ToJSON(*this); } diff --git a/contrib/llvm-project/lldb/source/Target/TargetProperties.td b/contrib/llvm-project/lldb/source/Target/TargetProperties.td index 8f627ad0f1a8..063ba0a6c25a 100644 --- a/contrib/llvm-project/lldb/source/Target/TargetProperties.td +++ b/contrib/llvm-project/lldb/source/Target/TargetProperties.td @@ -163,9 +163,6 @@ let Definition = "target" in { def DisplayRecognizedArguments: Property<"display-recognized-arguments", "Boolean">, DefaultFalse, Desc<"Show recognized arguments in variable listings by default.">; - def NonStopModeEnabled: Property<"non-stop-mode", "Boolean">, - DefaultFalse, - Desc<"Disable lock-step debugging, instead control threads independently.">; def RequireHardwareBreakpoints: Property<"require-hardware-breakpoint", "Boolean">, DefaultFalse, Desc<"Require all breakpoints to be hardware breakpoints.">; @@ -239,6 +236,10 @@ let Definition = "process" in { def VirtualAddressableBits: Property<"virtual-addressable-bits", "UInt64">, DefaultUnsignedValue<0>, Desc<"The number of bits used for addressing. If the value is 39, then bits 0..38 are used for addressing. The default value of 0 means unspecified.">; + def FollowForkMode: Property<"follow-fork-mode", "Enum">, + DefaultEnumValue<"eFollowParent">, + EnumValues<"OptionEnumValues(g_follow_fork_mode_values)">, + Desc<"Debugger's behavior upon fork or vfork.">; } let Definition = "platform" in { diff --git a/contrib/llvm-project/lldb/source/Target/Thread.cpp b/contrib/llvm-project/lldb/source/Target/Thread.cpp index b423f1b5f1fe..1b32331d98f7 100644 --- a/contrib/llvm-project/lldb/source/Target/Thread.cpp +++ b/contrib/llvm-project/lldb/source/Target/Thread.cpp @@ -55,12 +55,11 @@ using namespace lldb; using namespace lldb_private; -const ThreadPropertiesSP &Thread::GetGlobalProperties() { +ThreadProperties &Thread::GetGlobalProperties() { // NOTE: intentional leak so we don't crash if global destructor chain gets // called as other threads still use the result of this function - static ThreadPropertiesSP *g_settings_sp_ptr = - new ThreadPropertiesSP(new ThreadProperties(true)); - return *g_settings_sp_ptr; + static ThreadProperties *g_settings_ptr = new ThreadProperties(true); + return *g_settings_ptr; } #define LLDB_PROPERTIES_thread @@ -103,7 +102,7 @@ ThreadProperties::ThreadProperties(bool is_global) : Properties() { m_collection_sp->Initialize(g_thread_properties); } else m_collection_sp = - OptionValueProperties::CreateLocalCopy(*Thread::GetGlobalProperties()); + OptionValueProperties::CreateLocalCopy(Thread::GetGlobalProperties()); } ThreadProperties::~ThreadProperties() = default; @@ -845,7 +844,7 @@ bool Thread::ShouldStop(Event *event_ptr) { // we're done, otherwise we forward this to the next plan in the // stack below. done_processing_current_plan = - (plan_ptr->IsMasterPlan() && !plan_ptr->OkayToDiscard()); + (plan_ptr->IsControllingPlan() && !plan_ptr->OkayToDiscard()); } else done_processing_current_plan = true; @@ -883,11 +882,11 @@ bool Thread::ShouldStop(Event *event_ptr) { current_plan->GetName()); } - // If a Master Plan wants to stop, we let it. Otherwise, see if the - // plan's parent wants to stop. + // If a Controlling Plan wants to stop, we let it. Otherwise, see if + // the plan's parent wants to stop. PopPlan(); - if (should_stop && current_plan->IsMasterPlan() && + if (should_stop && current_plan->IsControllingPlan() && !current_plan->OkayToDiscard()) { break; } @@ -906,8 +905,8 @@ bool Thread::ShouldStop(Event *event_ptr) { should_stop = false; } - // One other potential problem is that we set up a master plan, then stop in - // before it is complete - for instance by hitting a breakpoint during a + // One other potential problem is that we set up a controlling plan, then stop + // in before it is complete - for instance by hitting a breakpoint during a // step-over - then do some step/finish/etc operations that wind up past the // end point condition of the initial plan. We don't want to strand the // original plan on the stack, This code clears stale plans off the stack. @@ -1215,7 +1214,7 @@ void Thread::DiscardThreadPlans(bool force) { GetPlans().DiscardAllPlans(); return; } - GetPlans().DiscardConsultingMasterPlans(); + GetPlans().DiscardConsultingControllingPlans(); } Status Thread::UnwindInnermostExpression() { @@ -1915,7 +1914,7 @@ Status Thread::StepIn(bool source_step, false, abort_other_plans, run_mode, error); } - new_plan_sp->SetIsMasterPlan(true); + new_plan_sp->SetIsControllingPlan(true); new_plan_sp->SetOkayToDiscard(false); // Why do we need to set the current thread by ID here??? @@ -1948,7 +1947,7 @@ Status Thread::StepOver(bool source_step, true, abort_other_plans, run_mode, error); } - new_plan_sp->SetIsMasterPlan(true); + new_plan_sp->SetIsControllingPlan(true); new_plan_sp->SetOkayToDiscard(false); // Why do we need to set the current thread by ID here??? @@ -1972,7 +1971,7 @@ Status Thread::StepOut() { abort_other_plans, nullptr, first_instruction, stop_other_threads, eVoteYes, eVoteNoOpinion, 0, error)); - new_plan_sp->SetIsMasterPlan(true); + new_plan_sp->SetIsControllingPlan(true); new_plan_sp->SetOkayToDiscard(false); // Why do we need to set the current thread by ID here??? diff --git a/contrib/llvm-project/lldb/source/Target/ThreadPlan.cpp b/contrib/llvm-project/lldb/source/Target/ThreadPlan.cpp index 6b55f3912d11..3b42831f1fbf 100644 --- a/contrib/llvm-project/lldb/source/Target/ThreadPlan.cpp +++ b/contrib/llvm-project/lldb/source/Target/ThreadPlan.cpp @@ -26,8 +26,8 @@ ThreadPlan::ThreadPlan(ThreadPlanKind kind, const char *name, Thread &thread, m_takes_iteration_count(false), m_could_not_resolve_hw_bp(false), m_thread(&thread), m_kind(kind), m_name(name), m_plan_complete_mutex(), m_cached_plan_explains_stop(eLazyBoolCalculate), m_plan_complete(false), - m_plan_private(false), m_okay_to_discard(true), m_is_master_plan(false), - m_plan_succeeded(true) { + m_plan_private(false), m_okay_to_discard(true), + m_is_controlling_plan(false), m_plan_succeeded(true) { SetID(GetNextID()); } @@ -149,10 +149,10 @@ lldb::user_id_t ThreadPlan::GetNextID() { void ThreadPlan::DidPush() {} -void ThreadPlan::WillPop() {} +void ThreadPlan::DidPop() {} bool ThreadPlan::OkayToDiscard() { - return IsMasterPlan() ? m_okay_to_discard : true; + return IsControllingPlan() ? m_okay_to_discard : true; } lldb::StateType ThreadPlan::RunState() { diff --git a/contrib/llvm-project/lldb/source/Target/ThreadPlanBase.cpp b/contrib/llvm-project/lldb/source/Target/ThreadPlanBase.cpp index c6c4d97c1655..46ae9c32a0de 100644 --- a/contrib/llvm-project/lldb/source/Target/ThreadPlanBase.cpp +++ b/contrib/llvm-project/lldb/source/Target/ThreadPlanBase.cpp @@ -40,7 +40,7 @@ ThreadPlanBase::ThreadPlanBase(Thread &thread) #endif new_tracer_sp->EnableTracing(thread.GetTraceEnabledState()); SetThreadPlanTracer(new_tracer_sp); - SetIsMasterPlan(true); + SetIsControllingPlan(true); } ThreadPlanBase::~ThreadPlanBase() = default; @@ -90,8 +90,8 @@ bool ThreadPlanBase::ShouldStop(Event *event_ptr) { case eStopReasonWatchpoint: if (stop_info_sp->ShouldStopSynchronous(event_ptr)) { // If we are going to stop for a breakpoint, then unship the other - // plans at this point. Don't force the discard, however, so Master - // plans can stay in place if they want to. + // plans at this point. Don't force the discard, however, so + // Controlling plans can stay in place if they want to. LLDB_LOGF( log, "Base plan discarding thread plans for thread tid = 0x%4.4" PRIx64 diff --git a/contrib/llvm-project/lldb/source/Target/ThreadPlanCallFunction.cpp b/contrib/llvm-project/lldb/source/Target/ThreadPlanCallFunction.cpp index 3699a507d058..0336a9daf10a 100644 --- a/contrib/llvm-project/lldb/source/Target/ThreadPlanCallFunction.cpp +++ b/contrib/llvm-project/lldb/source/Target/ThreadPlanCallFunction.cpp @@ -33,7 +33,7 @@ using namespace lldb_private; bool ThreadPlanCallFunction::ConstructorSetup( Thread &thread, ABI *&abi, lldb::addr_t &start_load_addr, lldb::addr_t &function_load_addr) { - SetIsMasterPlan(true); + SetIsControllingPlan(true); SetOkayToDiscard(false); SetPrivate(true); @@ -209,7 +209,7 @@ void ThreadPlanCallFunction::DoTakedown(bool success) { } } -void ThreadPlanCallFunction::WillPop() { DoTakedown(PlanSucceeded()); } +void ThreadPlanCallFunction::DidPop() { DoTakedown(PlanSucceeded()); } void ThreadPlanCallFunction::GetDescription(Stream *s, DescriptionLevel level) { if (level == eDescriptionLevelBrief) { diff --git a/contrib/llvm-project/lldb/source/Target/ThreadPlanCallOnFunctionExit.cpp b/contrib/llvm-project/lldb/source/Target/ThreadPlanCallOnFunctionExit.cpp index 7471e9b3d7ac..4bccf96d721b 100644 --- a/contrib/llvm-project/lldb/source/Target/ThreadPlanCallOnFunctionExit.cpp +++ b/contrib/llvm-project/lldb/source/Target/ThreadPlanCallOnFunctionExit.cpp @@ -18,7 +18,7 @@ ThreadPlanCallOnFunctionExit::ThreadPlanCallOnFunctionExit( ), m_callback(callback) { // We are not a user-generated plan. - SetIsMasterPlan(false); + SetIsControllingPlan(false); } void ThreadPlanCallOnFunctionExit::DidPush() { diff --git a/contrib/llvm-project/lldb/source/Target/ThreadPlanCallUserExpression.cpp b/contrib/llvm-project/lldb/source/Target/ThreadPlanCallUserExpression.cpp index 9dddd850b6ab..d833a4d7ed27 100644 --- a/contrib/llvm-project/lldb/source/Target/ThreadPlanCallUserExpression.cpp +++ b/contrib/llvm-project/lldb/source/Target/ThreadPlanCallUserExpression.cpp @@ -39,7 +39,7 @@ ThreadPlanCallUserExpression::ThreadPlanCallUserExpression( m_user_expression_sp(user_expression_sp) { // User expressions are generally "User generated" so we should set them up // to stop when done. - SetIsMasterPlan(true); + SetIsControllingPlan(true); SetOkayToDiscard(false); } @@ -59,8 +59,8 @@ void ThreadPlanCallUserExpression::DidPush() { m_user_expression_sp->WillStartExecuting(); } -void ThreadPlanCallUserExpression::WillPop() { - ThreadPlanCallFunction::WillPop(); +void ThreadPlanCallUserExpression::DidPop() { + ThreadPlanCallFunction::DidPop(); if (m_user_expression_sp) m_user_expression_sp.reset(); } diff --git a/contrib/llvm-project/lldb/source/Target/ThreadPlanPython.cpp b/contrib/llvm-project/lldb/source/Target/ThreadPlanPython.cpp index e83f0e9e715e..cd63d28a3934 100644 --- a/contrib/llvm-project/lldb/source/Target/ThreadPlanPython.cpp +++ b/contrib/llvm-project/lldb/source/Target/ThreadPlanPython.cpp @@ -31,7 +31,7 @@ ThreadPlanPython::ThreadPlanPython(Thread &thread, const char *class_name, eVoteNoOpinion, eVoteNoOpinion), m_class_name(class_name), m_args_data(args_data), m_did_push(false), m_stop_others(false) { - SetIsMasterPlan(true); + SetIsControllingPlan(true); SetOkayToDiscard(true); SetPrivate(false); } diff --git a/contrib/llvm-project/lldb/source/Target/ThreadPlanStack.cpp b/contrib/llvm-project/lldb/source/Target/ThreadPlanStack.cpp index d25602d25b91..f09583cc50cc 100644 --- a/contrib/llvm-project/lldb/source/Target/ThreadPlanStack.cpp +++ b/contrib/llvm-project/lldb/source/Target/ThreadPlanStack.cpp @@ -150,10 +150,13 @@ lldb::ThreadPlanSP ThreadPlanStack::PopPlan() { std::lock_guard<std::recursive_mutex> guard(m_stack_mutex); assert(m_plans.size() > 1 && "Can't pop the base thread plan"); - lldb::ThreadPlanSP plan_sp = std::move(m_plans.back()); - m_completed_plans.push_back(plan_sp); - plan_sp->WillPop(); + // Note that moving the top element of the vector would leave it in an + // undefined state, and break the guarantee that the stack's thread plans are + // all valid. + lldb::ThreadPlanSP plan_sp = m_plans.back(); m_plans.pop_back(); + m_completed_plans.push_back(plan_sp); + plan_sp->DidPop(); return plan_sp; } @@ -161,10 +164,13 @@ lldb::ThreadPlanSP ThreadPlanStack::DiscardPlan() { std::lock_guard<std::recursive_mutex> guard(m_stack_mutex); assert(m_plans.size() > 1 && "Can't discard the base thread plan"); - lldb::ThreadPlanSP plan_sp = std::move(m_plans.back()); - m_discarded_plans.push_back(plan_sp); - plan_sp->WillPop(); + // Note that moving the top element of the vector would leave it in an + // undefined state, and break the guarantee that the stack's thread plans are + // all valid. + lldb::ThreadPlanSP plan_sp = m_plans.back(); m_plans.pop_back(); + m_discarded_plans.push_back(plan_sp); + plan_sp->DidPop(); return plan_sp; } @@ -207,35 +213,35 @@ void ThreadPlanStack::DiscardAllPlans() { return; } -void ThreadPlanStack::DiscardConsultingMasterPlans() { +void ThreadPlanStack::DiscardConsultingControllingPlans() { std::lock_guard<std::recursive_mutex> guard(m_stack_mutex); while (true) { - int master_plan_idx; + int controlling_plan_idx; bool discard = true; - // Find the first master plan, see if it wants discarding, and if yes + // Find the first controlling plan, see if it wants discarding, and if yes // discard up to it. - for (master_plan_idx = m_plans.size() - 1; master_plan_idx >= 0; - master_plan_idx--) { - if (m_plans[master_plan_idx]->IsMasterPlan()) { - discard = m_plans[master_plan_idx]->OkayToDiscard(); + for (controlling_plan_idx = m_plans.size() - 1; controlling_plan_idx >= 0; + controlling_plan_idx--) { + if (m_plans[controlling_plan_idx]->IsControllingPlan()) { + discard = m_plans[controlling_plan_idx]->OkayToDiscard(); break; } } - // If the master plan doesn't want to get discarded, then we're done. + // If the controlling plan doesn't want to get discarded, then we're done. if (!discard) return; // First pop all the dependent plans: - for (int i = m_plans.size() - 1; i > master_plan_idx; i--) { + for (int i = m_plans.size() - 1; i > controlling_plan_idx; i--) { DiscardPlan(); } - // Now discard the master plan itself. + // Now discard the controlling plan itself. // The bottom-most plan never gets discarded. "OkayToDiscard" for it // means discard it's dependent plans, but not it... - if (master_plan_idx > 0) { + if (controlling_plan_idx > 0) { DiscardPlan(); } } diff --git a/contrib/llvm-project/lldb/source/Target/ThreadPlanStepOverBreakpoint.cpp b/contrib/llvm-project/lldb/source/Target/ThreadPlanStepOverBreakpoint.cpp index 965a7b3a9960..f007b0fa9371 100644 --- a/contrib/llvm-project/lldb/source/Target/ThreadPlanStepOverBreakpoint.cpp +++ b/contrib/llvm-project/lldb/source/Target/ThreadPlanStepOverBreakpoint.cpp @@ -124,9 +124,7 @@ bool ThreadPlanStepOverBreakpoint::WillStop() { return true; } -void ThreadPlanStepOverBreakpoint::WillPop() { - ReenableBreakpointSite(); -} +void ThreadPlanStepOverBreakpoint::DidPop() { ReenableBreakpointSite(); } bool ThreadPlanStepOverBreakpoint::MischiefManaged() { lldb::addr_t pc_addr = GetThread().GetRegisterContext()->GetPC(); diff --git a/contrib/llvm-project/lldb/source/Target/Trace.cpp b/contrib/llvm-project/lldb/source/Target/Trace.cpp index 827f3264c096..38b3a7cb006d 100644 --- a/contrib/llvm-project/lldb/source/Target/Trace.cpp +++ b/contrib/llvm-project/lldb/source/Target/Trace.cpp @@ -67,30 +67,28 @@ Trace::FindPluginForPostMortemProcess(Debugger &debugger, if (!json::fromJSON(trace_session_file, json_session, root)) return root.getError(); - ConstString plugin_name(json_session.trace.type); - if (auto create_callback = PluginManager::GetTraceCreateCallback(plugin_name)) + if (auto create_callback = + PluginManager::GetTraceCreateCallback(json_session.trace.type)) return create_callback(trace_session_file, session_file_dir, debugger); return createInvalidPlugInError(json_session.trace.type); } -Expected<lldb::TraceSP> -Trace::FindPluginForLiveProcess(llvm::StringRef plugin_name, Process &process) { +Expected<lldb::TraceSP> Trace::FindPluginForLiveProcess(llvm::StringRef name, + Process &process) { if (!process.IsLiveDebugSession()) return createStringError(inconvertibleErrorCode(), "Can't trace non-live processes"); - ConstString name(plugin_name); if (auto create_callback = PluginManager::GetTraceCreateCallbackForLiveProcess(name)) return create_callback(process); - return createInvalidPlugInError(plugin_name); + return createInvalidPlugInError(name); } Expected<StringRef> Trace::FindPluginSchema(StringRef name) { - ConstString plugin_name(name); - StringRef schema = PluginManager::GetTraceSchema(plugin_name); + StringRef schema = PluginManager::GetTraceSchema(name); if (!schema.empty()) return schema; @@ -108,23 +106,21 @@ Error Trace::Stop() { if (!m_live_process) return createStringError(inconvertibleErrorCode(), "Tracing requires a live process."); - return m_live_process->TraceStop( - TraceStopRequest(GetPluginName().AsCString())); + return m_live_process->TraceStop(TraceStopRequest(GetPluginName())); } Error Trace::Stop(llvm::ArrayRef<lldb::tid_t> tids) { if (!m_live_process) return createStringError(inconvertibleErrorCode(), "Tracing requires a live process."); - return m_live_process->TraceStop( - TraceStopRequest(GetPluginName().AsCString(), tids)); + return m_live_process->TraceStop(TraceStopRequest(GetPluginName(), tids)); } Expected<std::string> Trace::GetLiveProcessState() { if (!m_live_process) return createStringError(inconvertibleErrorCode(), "Tracing requires a live process."); - return m_live_process->TraceGetState(GetPluginName().AsCString()); + return m_live_process->TraceGetState(GetPluginName()); } Optional<size_t> Trace::GetLiveThreadBinaryDataSize(lldb::tid_t tid, @@ -158,7 +154,7 @@ Trace::GetLiveThreadBinaryData(lldb::tid_t tid, llvm::StringRef kind) { "Tracing data \"%s\" is not available for thread %" PRIu64 ".", kind.data(), tid); - TraceGetBinaryDataRequest request{GetPluginName().AsCString(), kind.str(), + TraceGetBinaryDataRequest request{GetPluginName().str(), kind.str(), static_cast<int64_t>(tid), 0, static_cast<int64_t>(*size)}; return m_live_process->TraceGetBinaryData(request); @@ -175,8 +171,8 @@ Trace::GetLiveProcessBinaryData(llvm::StringRef kind) { inconvertibleErrorCode(), "Tracing data \"%s\" is not available for the process.", kind.data()); - TraceGetBinaryDataRequest request{GetPluginName().AsCString(), kind.str(), - None, 0, static_cast<int64_t>(*size)}; + TraceGetBinaryDataRequest request{GetPluginName().str(), kind.str(), None, 0, + static_cast<int64_t>(*size)}; return m_live_process->TraceGetBinaryData(request); } diff --git a/contrib/llvm-project/lldb/source/Target/TraceExporter.cpp b/contrib/llvm-project/lldb/source/Target/TraceExporter.cpp index 1a6571dba4a0..8c925aa495b0 100644 --- a/contrib/llvm-project/lldb/source/Target/TraceExporter.cpp +++ b/contrib/llvm-project/lldb/source/Target/TraceExporter.cpp @@ -22,11 +22,10 @@ static Error createInvalidPlugInError(StringRef plugin_name) { } Expected<lldb::TraceExporterUP> -TraceExporter::FindPlugin(llvm::StringRef plugin_name) { - ConstString name(plugin_name); +TraceExporter::FindPlugin(llvm::StringRef name) { if (auto create_callback = PluginManager::GetTraceExporterCreateCallback(name)) return create_callback(); - return createInvalidPlugInError(plugin_name); + return createInvalidPlugInError(name); } diff --git a/contrib/llvm-project/lldb/source/Target/UnixSignals.cpp b/contrib/llvm-project/lldb/source/Target/UnixSignals.cpp index 4ec2e25c7e3b..26ff0bbd3825 100644 --- a/contrib/llvm-project/lldb/source/Target/UnixSignals.cpp +++ b/contrib/llvm-project/lldb/source/Target/UnixSignals.cpp @@ -12,10 +12,10 @@ #include "Plugins/Process/Utility/MipsLinuxSignals.h" #include "Plugins/Process/Utility/NetBSDSignals.h" #include "lldb/Host/HostInfo.h" -#include "lldb/Host/StringConvert.h" #include "lldb/Utility/ArchSpec.h" using namespace lldb_private; +using namespace llvm; UnixSignals::Signal::Signal(const char *name, bool default_suppress, bool default_stop, bool default_notify, @@ -156,9 +156,8 @@ int32_t UnixSignals::GetSignalNumberFromName(const char *name) const { return pos->first; } - const int32_t signo = - StringConvert::ToSInt32(name, LLDB_INVALID_SIGNAL_NUMBER, 0); - if (signo != LLDB_INVALID_SIGNAL_NUMBER) + int32_t signo; + if (llvm::to_integer(name, signo)) return signo; return LLDB_INVALID_SIGNAL_NUMBER; } @@ -314,3 +313,20 @@ UnixSignals::GetFilteredSignals(llvm::Optional<bool> should_suppress, return result; } + +void UnixSignals::IncrementSignalHitCount(int signo) { + collection::iterator pos = m_signals.find(signo); + if (pos != m_signals.end()) + pos->second.m_hit_count += 1; +} + +json::Value UnixSignals::GetHitCountStatistics() const { + json::Array json_signals; + for (const auto &pair: m_signals) { + if (pair.second.m_hit_count > 0) + json_signals.emplace_back(json::Object{ + { pair.second.m_name.GetCString(), pair.second.m_hit_count } + }); + } + return std::move(json_signals); +} diff --git a/contrib/llvm-project/lldb/source/Utility/Environment.cpp b/contrib/llvm-project/lldb/source/Utility/Environment.cpp index 5666c2c12ffd..419e0745671a 100644 --- a/contrib/llvm-project/lldb/source/Utility/Environment.cpp +++ b/contrib/llvm-project/lldb/source/Utility/Environment.cpp @@ -41,7 +41,7 @@ Environment::Environment(const char *const *Env) { insert(*Env++); } -void Environment::insert(const_iterator first, const_iterator last) { +void Environment::insert(iterator first, iterator last) { while (first != last) { try_emplace(first->first(), first->second); ++first; diff --git a/contrib/llvm-project/lldb/source/Utility/FileSpec.cpp b/contrib/llvm-project/lldb/source/Utility/FileSpec.cpp index bea3c6d6268b..601edb86c1b0 100644 --- a/contrib/llvm-project/lldb/source/Utility/FileSpec.cpp +++ b/contrib/llvm-project/lldb/source/Utility/FileSpec.cpp @@ -43,9 +43,7 @@ static constexpr FileSpec::Style GetNativeStyle() { } bool PathStyleIsPosix(FileSpec::Style style) { - return (style == FileSpec::Style::posix || - (style == FileSpec::Style::native && - GetNativeStyle() == FileSpec::Style::posix)); + return llvm::sys::path::is_style_posix(style); } const char *GetPathSeparators(FileSpec::Style style) { diff --git a/contrib/llvm-project/lldb/source/Utility/ReproducerInstrumentation.cpp b/contrib/llvm-project/lldb/source/Utility/ReproducerInstrumentation.cpp index e5bd2ba4b625..b3285f4b3776 100644 --- a/contrib/llvm-project/lldb/source/Utility/ReproducerInstrumentation.cpp +++ b/contrib/llvm-project/lldb/source/Utility/ReproducerInstrumentation.cpp @@ -16,6 +16,9 @@ using namespace lldb_private; using namespace lldb_private::repro; +// Whether we're currently across the API boundary. +static thread_local bool g_global_boundary = false; + void *IndexToObject::GetObjectForIndexImpl(unsigned idx) { return m_mapping.lookup(idx); } @@ -227,6 +230,13 @@ unsigned Recorder::GetSequenceNumber() const { return m_sequence; } +void Recorder::PrivateThread() { g_global_boundary = true; } + +void Recorder::UpdateBoundary() { + if (m_local_boundary) + g_global_boundary = false; +} + void InstrumentationData::Initialize(Serializer &serializer, Registry ®istry) { InstanceImpl().emplace(serializer, registry); @@ -248,6 +258,5 @@ llvm::Optional<InstrumentationData> &InstrumentationData::InstanceImpl() { return g_instrumentation_data; } -thread_local bool lldb_private::repro::Recorder::g_global_boundary = false; std::atomic<unsigned> lldb_private::repro::Recorder::g_sequence; std::mutex lldb_private::repro::Recorder::g_mutex; diff --git a/contrib/llvm-project/lldb/source/Utility/Scalar.cpp b/contrib/llvm-project/lldb/source/Utility/Scalar.cpp index e0b26e89f3c1..19e00e111be5 100644 --- a/contrib/llvm-project/lldb/source/Utility/Scalar.cpp +++ b/contrib/llvm-project/lldb/source/Utility/Scalar.cpp @@ -714,7 +714,7 @@ Status Scalar::SetValueFromData(const DataExtractor &data, return Status("insufficient data"); m_type = e_int; m_integer = - APSInt(APInt::getNullValue(8 * byte_size), encoding == eEncodingUint); + APSInt(APInt::getZero(8 * byte_size), encoding == eEncodingUint); if (data.GetByteOrder() == endian::InlHostByteOrder()) { llvm::LoadIntFromMemory(m_integer, data.GetDataStart(), byte_size); } else { diff --git a/contrib/llvm-project/lldb/source/Utility/Status.cpp b/contrib/llvm-project/lldb/source/Utility/Status.cpp index 72fd087decc0..e6d381421f28 100644 --- a/contrib/llvm-project/lldb/source/Utility/Status.cpp +++ b/contrib/llvm-project/lldb/source/Utility/Status.cpp @@ -287,10 +287,6 @@ int Status::SetErrorStringWithVarArg(const char *format, va_list args) { // return value. bool Status::Success() const { return m_code == 0; } -bool Status::WasInterrupted() const { - return (m_type == eErrorTypePOSIX && m_code == EINTR); -} - void llvm::format_provider<lldb_private::Status>::format( const lldb_private::Status &error, llvm::raw_ostream &OS, llvm::StringRef Options) { diff --git a/contrib/llvm-project/lldb/source/Utility/StringExtractorGDBRemote.cpp b/contrib/llvm-project/lldb/source/Utility/StringExtractorGDBRemote.cpp index 29cf585bea56..d6bbf7171916 100644 --- a/contrib/llvm-project/lldb/source/Utility/StringExtractorGDBRemote.cpp +++ b/contrib/llvm-project/lldb/source/Utility/StringExtractorGDBRemote.cpp @@ -260,6 +260,8 @@ StringExtractorGDBRemote::GetServerPacketType() const { break; case 'S': + if (PACKET_STARTS_WITH("qSaveCore")) + return eServerPacketType_qLLDBSaveCore; if (PACKET_STARTS_WITH("qSpeedTest:")) return eServerPacketType_qSpeedTest; if (PACKET_MATCHES("qShlibInfoAddr")) @@ -337,6 +339,8 @@ StringExtractorGDBRemote::GetServerPacketType() const { return eServerPacketType_vFile_size; else if (PACKET_STARTS_WITH("vFile:exists")) return eServerPacketType_vFile_exists; + else if (PACKET_STARTS_WITH("vFile:fstat")) + return eServerPacketType_vFile_fstat; else if (PACKET_STARTS_WITH("vFile:stat")) return eServerPacketType_vFile_stat; else if (PACKET_STARTS_WITH("vFile:mode")) @@ -361,6 +365,8 @@ StringExtractorGDBRemote::GetServerPacketType() const { return eServerPacketType_vCont; if (PACKET_MATCHES("vCont?")) return eServerPacketType_vCont_actions; + if (PACKET_STARTS_WITH("vRun;")) + return eServerPacketType_vRun; } break; case '_': diff --git a/contrib/llvm-project/lldb/source/Utility/Timer.cpp b/contrib/llvm-project/lldb/source/Utility/Timer.cpp index b59ce3b9f556..2f3afe4c8703 100644 --- a/contrib/llvm-project/lldb/source/Utility/Timer.cpp +++ b/contrib/llvm-project/lldb/source/Utility/Timer.cpp @@ -33,8 +33,6 @@ static std::atomic<Timer::Category *> g_categories; /// Allows llvm::Timer to emit signposts when supported. static llvm::ManagedStatic<llvm::SignpostEmitter> Signposts; -llvm::SignpostEmitter &lldb_private::GetSignposts() { return *Signposts; } - std::atomic<bool> Timer::g_quiet(true); std::atomic<unsigned> Timer::g_display_depth(0); static std::mutex &GetFileMutex() { @@ -61,6 +59,7 @@ void Timer::SetQuiet(bool value) { g_quiet = value; } Timer::Timer(Timer::Category &category, const char *format, ...) : m_category(category), m_total_start(std::chrono::steady_clock::now()) { + Signposts->startInterval(this, m_category.GetName()); TimerStack &stack = GetTimerStackForCurrentThread(); stack.push_back(this); @@ -87,6 +86,8 @@ Timer::~Timer() { auto total_dur = stop_time - m_total_start; auto timer_dur = total_dur - m_child_duration; + Signposts->endInterval(this, m_category.GetName()); + TimerStack &stack = GetTimerStackForCurrentThread(); if (g_quiet && stack.size() <= g_display_depth) { std::lock_guard<std::mutex> lock(GetFileMutex()); diff --git a/contrib/llvm-project/lldb/source/Utility/UriParser.cpp b/contrib/llvm-project/lldb/source/Utility/UriParser.cpp index c6ed24985896..cfb9009898d2 100644 --- a/contrib/llvm-project/lldb/source/Utility/UriParser.cpp +++ b/contrib/llvm-project/lldb/source/Utility/UriParser.cpp @@ -7,6 +7,7 @@ //===----------------------------------------------------------------------===// #include "lldb/Utility/UriParser.h" +#include "llvm/Support/raw_ostream.h" #include <string> @@ -15,25 +16,30 @@ using namespace lldb_private; -// UriParser::Parse -bool UriParser::Parse(llvm::StringRef uri, llvm::StringRef &scheme, - llvm::StringRef &hostname, int &port, - llvm::StringRef &path) { - llvm::StringRef tmp_scheme, tmp_hostname, tmp_path; +llvm::raw_ostream &lldb_private::operator<<(llvm::raw_ostream &OS, + const URI &U) { + OS << U.scheme << "://[" << U.hostname << ']'; + if (U.port) + OS << ':' << U.port.getValue(); + return OS << U.path; +} + +llvm::Optional<URI> URI::Parse(llvm::StringRef uri) { + URI ret; const llvm::StringRef kSchemeSep("://"); auto pos = uri.find(kSchemeSep); if (pos == std::string::npos) - return false; + return llvm::None; // Extract path. - tmp_scheme = uri.substr(0, pos); + ret.scheme = uri.substr(0, pos); auto host_pos = pos + kSchemeSep.size(); auto path_pos = uri.find('/', host_pos); if (path_pos != std::string::npos) - tmp_path = uri.substr(path_pos); + ret.path = uri.substr(path_pos); else - tmp_path = "/"; + ret.path = "/"; auto host_port = uri.substr( host_pos, @@ -44,27 +50,24 @@ bool UriParser::Parse(llvm::StringRef uri, llvm::StringRef &scheme, // hostname is enclosed with square brackets. pos = host_port.rfind(']'); if (pos == std::string::npos) - return false; + return llvm::None; - tmp_hostname = host_port.substr(1, pos - 1); + ret.hostname = host_port.substr(1, pos - 1); host_port = host_port.drop_front(pos + 1); if (!host_port.empty() && !host_port.consume_front(":")) - return false; + return llvm::None; } else { - std::tie(tmp_hostname, host_port) = host_port.split(':'); + std::tie(ret.hostname, host_port) = host_port.split(':'); } // Extract port if (!host_port.empty()) { uint16_t port_value = 0; if (host_port.getAsInteger(0, port_value)) - return false; - port = port_value; + return llvm::None; + ret.port = port_value; } else - port = -1; + ret.port = llvm::None; - scheme = tmp_scheme; - hostname = tmp_hostname; - path = tmp_path; - return true; + return ret; } diff --git a/contrib/llvm-project/lldb/source/Utility/VMRange.cpp b/contrib/llvm-project/lldb/source/Utility/VMRange.cpp index 184531b4bb27..ddd2a67c29b2 100644 --- a/contrib/llvm-project/lldb/source/Utility/VMRange.cpp +++ b/contrib/llvm-project/lldb/source/Utility/VMRange.cpp @@ -23,16 +23,14 @@ using namespace lldb_private; bool VMRange::ContainsValue(const VMRange::collection &coll, lldb::addr_t value) { - return llvm::find_if(coll, [&](const VMRange &r) { - return r.Contains(value); - }) != coll.end(); + return llvm::any_of(coll, + [&](const VMRange &r) { return r.Contains(value); }); } bool VMRange::ContainsRange(const VMRange::collection &coll, const VMRange &range) { - return llvm::find_if(coll, [&](const VMRange &r) { - return r.Contains(range); - }) != coll.end(); + return llvm::any_of(coll, + [&](const VMRange &r) { return r.Contains(range); }); } void VMRange::Dump(llvm::raw_ostream &s, lldb::addr_t offset, diff --git a/contrib/llvm-project/lldb/tools/argdumper/argdumper.exports b/contrib/llvm-project/lldb/tools/argdumper/argdumper.exports deleted file mode 100644 index e69de29bb2d1..000000000000 --- a/contrib/llvm-project/lldb/tools/argdumper/argdumper.exports +++ /dev/null diff --git a/contrib/llvm-project/lldb/tools/compact-unwind/compact-unwind-dumper.c b/contrib/llvm-project/lldb/tools/compact-unwind/compact-unwind-dumper.c index d4706eaf5386..1551ed92597d 100644 --- a/contrib/llvm-project/lldb/tools/compact-unwind/compact-unwind-dumper.c +++ b/contrib/llvm-project/lldb/tools/compact-unwind/compact-unwind-dumper.c @@ -14,49 +14,6 @@ #include <sys/stat.h> #include <sys/types.h> -enum { - UNWIND_ARM64_MODE_MASK = 0x0F000000, - UNWIND_ARM64_MODE_FRAMELESS = 0x02000000, - UNWIND_ARM64_MODE_DWARF = 0x03000000, - UNWIND_ARM64_MODE_FRAME = 0x04000000, - - UNWIND_ARM64_FRAME_X19_X20_PAIR = 0x00000001, - UNWIND_ARM64_FRAME_X21_X22_PAIR = 0x00000002, - UNWIND_ARM64_FRAME_X23_X24_PAIR = 0x00000004, - UNWIND_ARM64_FRAME_X25_X26_PAIR = 0x00000008, - UNWIND_ARM64_FRAME_X27_X28_PAIR = 0x00000010, - UNWIND_ARM64_FRAME_D8_D9_PAIR = 0x00000100, - UNWIND_ARM64_FRAME_D10_D11_PAIR = 0x00000200, - UNWIND_ARM64_FRAME_D12_D13_PAIR = 0x00000400, - UNWIND_ARM64_FRAME_D14_D15_PAIR = 0x00000800, - - UNWIND_ARM64_FRAMELESS_STACK_SIZE_MASK = 0x00FFF000, - UNWIND_ARM64_DWARF_SECTION_OFFSET = 0x00FFFFFF, -}; - -enum { - UNWIND_ARM_MODE_MASK = 0x0F000000, - UNWIND_ARM_MODE_FRAME = 0x01000000, - UNWIND_ARM_MODE_FRAME_D = 0x02000000, - UNWIND_ARM_MODE_DWARF = 0x04000000, - - UNWIND_ARM_FRAME_STACK_ADJUST_MASK = 0x00C00000, - - UNWIND_ARM_FRAME_FIRST_PUSH_R4 = 0x00000001, - UNWIND_ARM_FRAME_FIRST_PUSH_R5 = 0x00000002, - UNWIND_ARM_FRAME_FIRST_PUSH_R6 = 0x00000004, - - UNWIND_ARM_FRAME_SECOND_PUSH_R8 = 0x00000008, - UNWIND_ARM_FRAME_SECOND_PUSH_R9 = 0x00000010, - UNWIND_ARM_FRAME_SECOND_PUSH_R10 = 0x00000020, - UNWIND_ARM_FRAME_SECOND_PUSH_R11 = 0x00000040, - UNWIND_ARM_FRAME_SECOND_PUSH_R12 = 0x00000080, - - UNWIND_ARM_FRAME_D_REG_COUNT_MASK = 0x00000700, - - UNWIND_ARM_DWARF_SECTION_OFFSET = 0x00FFFFFF, -}; - #define EXTRACT_BITS(value, mask) \ ((value >> __builtin_ctz(mask)) & (((1 << __builtin_popcount(mask))) - 1)) diff --git a/contrib/llvm-project/lldb/tools/driver/Driver.cpp b/contrib/llvm-project/lldb/tools/driver/Driver.cpp index a6a4a2a1b80b..a51c124f9615 100644 --- a/contrib/llvm-project/lldb/tools/driver/Driver.cpp +++ b/contrib/llvm-project/lldb/tools/driver/Driver.cpp @@ -18,6 +18,7 @@ #include "lldb/API/SBReproducer.h" #include "lldb/API/SBStream.h" #include "lldb/API/SBStringList.h" +#include "lldb/API/SBStructuredData.h" #include "llvm/ADT/StringRef.h" #include "llvm/Support/Format.h" @@ -201,6 +202,9 @@ SBError Driver::ProcessArgs(const opt::InputArgList &args, bool &exiting) { if (args.hasArg(OPT_python_path)) { m_option_data.m_print_python_path = true; } + if (args.hasArg(OPT_print_script_interpreter_info)) { + m_option_data.m_print_script_interpreter_info = true; + } if (args.hasArg(OPT_batch)) { m_option_data.m_batch = true; @@ -398,6 +402,22 @@ SBError Driver::ProcessArgs(const opt::InputArgList &args, bool &exiting) { return error; } + if (m_option_data.m_print_script_interpreter_info) { + SBStructuredData info = + m_debugger.GetScriptInterpreterInfo(m_debugger.GetScriptLanguage()); + if (!info) { + error.SetErrorString("no script interpreter."); + } else { + SBStream stream; + error = info.GetAsJSON(stream); + if (error.Success()) { + llvm::outs() << stream.GetData() << '\n'; + } + } + exiting = true; + return error; + } + return error; } @@ -609,6 +629,7 @@ int Driver::MainLoop() { options.SetSpawnThread(false); options.SetStopOnError(true); options.SetStopOnCrash(m_option_data.m_batch); + options.SetEchoCommands(!m_option_data.m_source_quietly); SBCommandInterpreterRunResult results = m_debugger.RunCommandInterpreter(options); diff --git a/contrib/llvm-project/lldb/tools/driver/Driver.h b/contrib/llvm-project/lldb/tools/driver/Driver.h index 2d91491a2540..d5779b3c2c91 100644 --- a/contrib/llvm-project/lldb/tools/driver/Driver.h +++ b/contrib/llvm-project/lldb/tools/driver/Driver.h @@ -79,6 +79,7 @@ public: bool m_source_quietly = false; bool m_print_version = false; bool m_print_python_path = false; + bool m_print_script_interpreter_info = false; bool m_wait_for = false; bool m_repl = false; bool m_batch = false; diff --git a/contrib/llvm-project/lldb/tools/driver/Options.td b/contrib/llvm-project/lldb/tools/driver/Options.td index 8bcb0e7bc52e..d59ac314d594 100644 --- a/contrib/llvm-project/lldb/tools/driver/Options.td +++ b/contrib/llvm-project/lldb/tools/driver/Options.td @@ -48,6 +48,10 @@ def: Flag<["-"], "P">, HelpText<"Alias for --python-path">, Group<grp_scripting>; +def print_script_interpreter_info: F<"print-script-interpreter-info">, + HelpText<"Prints out a json dictionary with information about the scripting language interpreter.">, + Group<grp_scripting>; + def script_language: Separate<["--", "-"], "script-language">, MetaVarName<"<language>">, HelpText<"Tells the debugger to use the specified scripting language for user-defined scripts.">, @@ -110,7 +114,7 @@ def: Flag<["-"], "b">, Group<grp_command>; def source_quietly: F<"source-quietly">, - HelpText<"Tells the debugger to execute this one-line lldb command before any file has been loaded.">, + HelpText<"Tells the debugger not to echo commands while sourcing files or one-line commands provided on the command line.">, Group<grp_command>; def: Flag<["-"], "Q">, Alias<source_quietly>, diff --git a/contrib/llvm-project/lldb/tools/driver/Platform.h b/contrib/llvm-project/lldb/tools/driver/Platform.h index d7573b75bf32..ff017c4422b1 100644 --- a/contrib/llvm-project/lldb/tools/driver/Platform.h +++ b/contrib/llvm-project/lldb/tools/driver/Platform.h @@ -9,19 +9,16 @@ #ifndef LLDB_TOOLS_DRIVER_PLATFORM_H #define LLDB_TOOLS_DRIVER_PLATFORM_H -#include "lldb/Host/Config.h" - #if defined(_WIN32) #include <io.h> #if defined(_MSC_VER) #include <csignal> #endif -#if HAVE_SYS_TYPES_H -#include <sys/types.h> -#endif + #include "lldb/Host/windows/windows.h" #include <cinttypes> +#include <sys/types.h> struct winsize { long ws_col; diff --git a/contrib/llvm-project/lldb/tools/lldb-server/Acceptor.cpp b/contrib/llvm-project/lldb/tools/lldb-server/Acceptor.cpp index b8be9c5c2661..4714252011aa 100644 --- a/contrib/llvm-project/lldb/tools/lldb-server/Acceptor.cpp +++ b/contrib/llvm-project/lldb/tools/lldb-server/Acceptor.cpp @@ -84,21 +84,16 @@ std::unique_ptr<Acceptor> Acceptor::Create(StringRef name, error.Clear(); Socket::SocketProtocol socket_protocol = Socket::ProtocolUnixDomain; - int port; - StringRef scheme, host, path; // Try to match socket name as URL - e.g., tcp://localhost:5555 - if (UriParser::Parse(name, scheme, host, port, path)) { - if (!FindProtocolByScheme(scheme.str().c_str(), socket_protocol)) + if (llvm::Optional<URI> res = URI::Parse(name)) { + if (!FindProtocolByScheme(res->scheme.str().c_str(), socket_protocol)) error.SetErrorStringWithFormat("Unknown protocol scheme \"%s\"", - scheme.str().c_str()); + res->scheme.str().c_str()); else - name = name.drop_front(scheme.size() + strlen("://")); + name = name.drop_front(res->scheme.size() + strlen("://")); } else { - std::string host_str; - std::string port_str; - int32_t port = INT32_MIN; // Try to match socket name as $host:port - e.g., localhost:5555 - if (Socket::DecodeHostAndPort(name, host_str, port_str, port, nullptr)) + if (!llvm::errorToBool(Socket::DecodeHostAndPort(name).takeError())) socket_protocol = Socket::ProtocolTcp; } diff --git a/contrib/llvm-project/lldb/tools/lldb-server/lldb-gdbserver.cpp b/contrib/llvm-project/lldb/tools/lldb-server/lldb-gdbserver.cpp index 888ba728fa91..906ae4c378b6 100644 --- a/contrib/llvm-project/lldb/tools/lldb-server/lldb-gdbserver.cpp +++ b/contrib/llvm-project/lldb/tools/lldb-server/lldb-gdbserver.cpp @@ -17,7 +17,6 @@ #include <unistd.h> #endif -#include "Acceptor.h" #include "LLDBServerUtilities.h" #include "Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h" #include "Plugins/Process/gdb-remote/ProcessGDBRemoteLog.h" @@ -26,7 +25,6 @@ #include "lldb/Host/FileSystem.h" #include "lldb/Host/Pipe.h" #include "lldb/Host/Socket.h" -#include "lldb/Host/StringConvert.h" #include "lldb/Host/common/NativeProcessProtocol.h" #include "lldb/Target/Process.h" #include "lldb/Utility/Status.h" @@ -165,15 +163,14 @@ void handle_launch(GDBRemoteCommunicationServerLLGS &gdb_server, } } -Status writeSocketIdToPipe(Pipe &port_pipe, const std::string &socket_id) { +Status writeSocketIdToPipe(Pipe &port_pipe, llvm::StringRef socket_id) { size_t bytes_written = 0; // Write the port number as a C string with the NULL terminator. - return port_pipe.Write(socket_id.c_str(), socket_id.size() + 1, - bytes_written); + return port_pipe.Write(socket_id.data(), socket_id.size() + 1, bytes_written); } Status writeSocketIdToPipe(const char *const named_pipe_path, - const std::string &socket_id) { + llvm::StringRef socket_id) { Pipe port_name_pipe; // Wait for 10 seconds for pipe to be opened. auto error = port_name_pipe.OpenAsWriterWithTimeout(named_pipe_path, false, @@ -184,7 +181,7 @@ Status writeSocketIdToPipe(const char *const named_pipe_path, } Status writeSocketIdToPipe(lldb::pipe_t unnamed_pipe, - const std::string &socket_id) { + llvm::StringRef socket_id) { Pipe port_pipe{LLDB_INVALID_PIPE, unnamed_pipe}; return writeSocketIdToPipe(port_pipe, socket_id); } @@ -198,129 +195,76 @@ void ConnectToRemote(MainLoop &mainloop, Status error; std::unique_ptr<Connection> connection_up; + std::string url; + if (connection_fd != -1) { - // Build the connection string. - char connection_url[512]; - snprintf(connection_url, sizeof(connection_url), "fd://%d", connection_fd); + url = llvm::formatv("fd://{0}", connection_fd).str(); // Create the connection. #if LLDB_ENABLE_POSIX && !defined _WIN32 ::fcntl(connection_fd, F_SETFD, FD_CLOEXEC); #endif - connection_up.reset(new ConnectionFileDescriptor); - auto connection_result = connection_up->Connect(connection_url, &error); - if (connection_result != eConnectionStatusSuccess) { - fprintf(stderr, "error: failed to connect to client at '%s' " - "(connection status: %d)\n", - connection_url, static_cast<int>(connection_result)); - exit(-1); - } - if (error.Fail()) { - fprintf(stderr, "error: failed to connect to client at '%s': %s\n", - connection_url, error.AsCString()); - exit(-1); - } } else if (!host_and_port.empty()) { - // Parse out host and port. - std::string final_host_and_port; - std::string connection_host; - std::string connection_port; - uint32_t connection_portno = 0; - - // If host_and_port starts with ':', default the host to be "localhost" and - // expect the remainder to be the port. - if (host_and_port[0] == ':') - final_host_and_port.append("localhost"); - final_host_and_port.append(host_and_port.str()); - - // Note: use rfind, because the host/port may look like "[::1]:12345". - const std::string::size_type colon_pos = final_host_and_port.rfind(':'); - if (colon_pos != std::string::npos) { - connection_host = final_host_and_port.substr(0, colon_pos); - connection_port = final_host_and_port.substr(colon_pos + 1); - connection_portno = StringConvert::ToUInt32(connection_port.c_str(), 0); + llvm::Expected<std::string> url_exp = + LLGSArgToURL(host_and_port, reverse_connect); + if (!url_exp) { + llvm::errs() << llvm::formatv("error: invalid host:port or URL '{0}': " + "{1}\n", + host_and_port, + llvm::toString(url_exp.takeError())); + exit(-1); } + url = std::move(url_exp.get()); + } - if (reverse_connect) { - // llgs will connect to the gdb-remote client. - - // Ensure we have a port number for the connection. - if (connection_portno == 0) { - fprintf(stderr, "error: port number must be specified on when using " - "reverse connect\n"); - exit(1); - } - - // Build the connection string. - char connection_url[512]; - snprintf(connection_url, sizeof(connection_url), "connect://%s", - final_host_and_port.c_str()); - - // Create the connection. - connection_up.reset(new ConnectionFileDescriptor); - auto connection_result = connection_up->Connect(connection_url, &error); - if (connection_result != eConnectionStatusSuccess) { - fprintf(stderr, "error: failed to connect to client at '%s' " - "(connection status: %d)\n", - connection_url, static_cast<int>(connection_result)); - exit(-1); - } - if (error.Fail()) { - fprintf(stderr, "error: failed to connect to client at '%s': %s\n", - connection_url, error.AsCString()); - exit(-1); - } - } else { - std::unique_ptr<Acceptor> acceptor_up( - Acceptor::Create(final_host_and_port, false, error)); - if (error.Fail()) { - fprintf(stderr, "failed to create acceptor: %s\n", error.AsCString()); - exit(1); - } - error = acceptor_up->Listen(1); - if (error.Fail()) { - fprintf(stderr, "failed to listen: %s\n", error.AsCString()); - exit(1); - } - const std::string socket_id = acceptor_up->GetLocalSocketId(); - if (!socket_id.empty()) { - // If we have a named pipe to write the socket id back to, do that now. - if (named_pipe_path && named_pipe_path[0]) { - error = writeSocketIdToPipe(named_pipe_path, socket_id); - if (error.Fail()) - fprintf(stderr, "failed to write to the named pipe \'%s\': %s\n", - named_pipe_path, error.AsCString()); - } - // If we have an unnamed pipe to write the socket id back to, do that - // now. - else if (unnamed_pipe != LLDB_INVALID_PIPE) { - error = writeSocketIdToPipe(unnamed_pipe, socket_id); - if (error.Fail()) - fprintf(stderr, "failed to write to the unnamed pipe: %s\n", - error.AsCString()); - } - } else { - fprintf(stderr, - "unable to get the socket id for the listening connection\n"); - } + if (!url.empty()) { + // Create the connection or server. + std::unique_ptr<ConnectionFileDescriptor> conn_fd_up{ + new ConnectionFileDescriptor}; + auto connection_result = conn_fd_up->Connect( + url, + [named_pipe_path, unnamed_pipe](llvm::StringRef socket_id) { + // If we have a named pipe to write the socket id back to, do that + // now. + if (named_pipe_path && named_pipe_path[0]) { + Status error = writeSocketIdToPipe(named_pipe_path, socket_id); + if (error.Fail()) + llvm::errs() << llvm::formatv( + "failed to write to the named peipe '{0}': {1}\n", + named_pipe_path, error.AsCString()); + } + // If we have an unnamed pipe to write the socket id back to, do + // that now. + else if (unnamed_pipe != LLDB_INVALID_PIPE) { + Status error = writeSocketIdToPipe(unnamed_pipe, socket_id); + if (error.Fail()) + llvm::errs() << llvm::formatv( + "failed to write to the unnamed pipe: {0}\n", error); + } + }, + &error); - Connection *conn = nullptr; - error = acceptor_up->Accept(false, conn); - if (error.Fail()) { - printf("failed to accept new connection: %s\n", error.AsCString()); - exit(1); - } - connection_up.reset(conn); + if (error.Fail()) { + llvm::errs() << llvm::formatv( + "error: failed to connect to client at '{0}': {1}\n", url, error); + exit(-1); + } + if (connection_result != eConnectionStatusSuccess) { + llvm::errs() << llvm::formatv( + "error: failed to connect to client at '{0}' " + "(connection status: {1})\n", + url, static_cast<int>(connection_result)); + exit(-1); } + connection_up = std::move(conn_fd_up); } error = gdb_server.InitializeConnection(std::move(connection_up)); if (error.Fail()) { - fprintf(stderr, "Failed to initialize connection: %s\n", - error.AsCString()); + llvm::errs() << llvm::formatv("failed to initialize connection\n", error); exit(-1); } - printf("Connection established.\n"); + llvm::outs() << "Connection established.\n"; } namespace { diff --git a/contrib/llvm-project/lldb/tools/lldb-server/lldb-server.exports b/contrib/llvm-project/lldb/tools/lldb-server/lldb-server.exports deleted file mode 100644 index e69de29bb2d1..000000000000 --- a/contrib/llvm-project/lldb/tools/lldb-server/lldb-server.exports +++ /dev/null |