aboutsummaryrefslogtreecommitdiff
path: root/source/Plugins/LanguageRuntime
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2016-07-23 20:50:09 +0000
committerDimitry Andric <dim@FreeBSD.org>2016-07-23 20:50:09 +0000
commitf3fbd1c0586ff6ec7895991e6c28f61a503c36a8 (patch)
tree48d008fd3df8c0e73271a4b18474e0aac6dbfe33 /source/Plugins/LanguageRuntime
parent2fc5d2d1dfaf623ce4e24cd8590565902f8c557c (diff)
downloadsrc-f3fbd1c0586ff6ec7895991e6c28f61a503c36a8.tar.gz
src-f3fbd1c0586ff6ec7895991e6c28f61a503c36a8.zip
Vendor import of lldb release_39 branch r276489:vendor/lldb/lldb-release_39-r276489
Notes
Notes: svn path=/vendor/lldb/dist/; revision=303241 svn path=/vendor/lldb/lldb-release_39-r276489/; revision=303242; tag=vendor/lldb/lldb-release_39-r276489
Diffstat (limited to 'source/Plugins/LanguageRuntime')
-rw-r--r--source/Plugins/LanguageRuntime/CMakeLists.txt1
-rw-r--r--source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp374
-rw-r--r--source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.h29
-rw-r--r--source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/Makefile14
-rw-r--r--source/Plugins/LanguageRuntime/Go/GoLanguageRuntime.cpp3
-rw-r--r--source/Plugins/LanguageRuntime/Go/Makefile14
-rw-r--r--source/Plugins/LanguageRuntime/Java/CMakeLists.txt3
-rw-r--r--source/Plugins/LanguageRuntime/Java/JavaLanguageRuntime.cpp176
-rw-r--r--source/Plugins/LanguageRuntime/Java/JavaLanguageRuntime.h90
-rw-r--r--source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.cpp10
-rw-r--r--source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.h5
-rw-r--r--source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.cpp50
-rw-r--r--source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp31
-rw-r--r--source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp1
-rw-r--r--source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp576
-rw-r--r--source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h44
-rw-r--r--source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.cpp58
-rw-r--r--source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.h6
-rw-r--r--source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.cpp9
-rw-r--r--source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.cpp19
-rw-r--r--source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/Makefile14
-rw-r--r--source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/Makefile14
-rw-r--r--source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.cpp2601
-rw-r--r--source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.h291
24 files changed, 2739 insertions, 1694 deletions
diff --git a/source/Plugins/LanguageRuntime/CMakeLists.txt b/source/Plugins/LanguageRuntime/CMakeLists.txt
index 66b17a4af229..2cf579212ec1 100644
--- a/source/Plugins/LanguageRuntime/CMakeLists.txt
+++ b/source/Plugins/LanguageRuntime/CMakeLists.txt
@@ -1,4 +1,5 @@
add_subdirectory(CPlusPlus)
add_subdirectory(ObjC)
add_subdirectory(Go)
+add_subdirectory(Java)
add_subdirectory(RenderScript)
diff --git a/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp b/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp
index 8e2cfb5570d9..c49feb07200e 100644
--- a/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp
+++ b/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp
@@ -13,13 +13,18 @@
#include "lldb/Core/ConstString.h"
#include "lldb/Core/Error.h"
#include "lldb/Core/Log.h"
+#include "lldb/Core/Mangled.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/PluginManager.h"
#include "lldb/Core/Scalar.h"
#include "lldb/Core/ValueObject.h"
#include "lldb/Core/ValueObjectMemory.h"
+#include "lldb/Interpreter/CommandObject.h"
+#include "lldb/Interpreter/CommandObjectMultiword.h"
+#include "lldb/Interpreter/CommandReturnObject.h"
#include "lldb/Symbol/ClangASTContext.h"
#include "lldb/Symbol/Symbol.h"
+#include "lldb/Symbol/SymbolFile.h"
#include "lldb/Symbol/TypeList.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/RegisterContext.h"
@@ -43,68 +48,26 @@ ItaniumABILanguageRuntime::CouldHaveDynamicValue (ValueObject &in_value)
return in_value.GetCompilerType().IsPossibleDynamicType (NULL, check_cxx, check_objc);
}
-bool
-ItaniumABILanguageRuntime::GetDynamicTypeAndAddress (ValueObject &in_value,
- lldb::DynamicValueType use_dynamic,
- TypeAndOrName &class_type_or_name,
- Address &dynamic_address,
- Value::ValueType &value_type)
+TypeAndOrName
+ItaniumABILanguageRuntime::GetTypeInfoFromVTableAddress(ValueObject &in_value, lldb::addr_t original_ptr,
+ lldb::addr_t vtable_load_addr)
{
- // For Itanium, if the type has a vtable pointer in the object, it will be at offset 0
- // in the object. That will point to the "address point" within the vtable (not the beginning of the
- // vtable.) We can then look up the symbol containing this "address point" and that symbol's name
- // demangled will contain the full class name.
- // The second pointer above the "address point" is the "offset_to_top". We'll use that to get the
- // start of the value object which holds the dynamic type.
- //
-
- class_type_or_name.Clear();
- value_type = Value::ValueType::eValueTypeScalar;
-
- // Only a pointer or reference type can have a different dynamic and static type:
- if (CouldHaveDynamicValue (in_value))
+ if (m_process && vtable_load_addr != LLDB_INVALID_ADDRESS)
{
- // First job, pull out the address at 0 offset from the object.
- AddressType address_type;
- lldb::addr_t original_ptr = in_value.GetPointerValue(&address_type);
- if (original_ptr == LLDB_INVALID_ADDRESS)
- return false;
-
- ExecutionContext exe_ctx (in_value.GetExecutionContextRef());
-
- Target *target = exe_ctx.GetTargetPtr();
- Process *process = exe_ctx.GetProcessPtr();
-
- char memory_buffer[16];
- DataExtractor data(memory_buffer, sizeof(memory_buffer),
- process->GetByteOrder(),
- process->GetAddressByteSize());
- size_t address_byte_size = process->GetAddressByteSize();
- Error error;
- size_t bytes_read = process->ReadMemory (original_ptr,
- memory_buffer,
- address_byte_size,
- error);
- if (!error.Success() || (bytes_read != address_byte_size))
- {
- return false;
- }
-
- lldb::offset_t offset = 0;
- lldb::addr_t vtable_address_point = data.GetAddress (&offset);
-
- if (offset == 0)
- return false;
-
- // Now find the symbol that contains this address:
-
- SymbolContext sc;
- Address address_point_address;
- if (target && !target->GetSectionLoadList().IsEmpty())
+ // Find the symbol that contains the "vtable_load_addr" address
+ Address vtable_addr;
+ Target &target = m_process->GetTarget();
+ if (!target.GetSectionLoadList().IsEmpty())
{
- if (target->GetSectionLoadList().ResolveLoadAddress (vtable_address_point, address_point_address))
+ if (target.GetSectionLoadList().ResolveLoadAddress(vtable_load_addr, vtable_addr))
{
- target->GetImages().ResolveSymbolContextForAddress (address_point_address, eSymbolContextSymbol, sc);
+ // See if we have cached info for this type already
+ TypeAndOrName type_info = GetDynamicTypeInfo(vtable_addr);
+ if (type_info)
+ return type_info;
+
+ SymbolContext sc;
+ target.GetImages().ResolveSymbolContextForAddress(vtable_addr, eSymbolContextSymbol, sc);
Symbol *symbol = sc.symbol;
if (symbol != NULL)
{
@@ -119,52 +82,56 @@ ItaniumABILanguageRuntime::GetDynamicTypeAndAddress (ValueObject &in_value,
name);
// We are a C++ class, that's good. Get the class name and look it up:
const char *class_name = name + strlen(vtable_demangled_prefix);
- class_type_or_name.SetName (class_name);
+ type_info.SetName(class_name);
const bool exact_match = true;
TypeList class_types;
-
+
uint32_t num_matches = 0;
// First look in the module that the vtable symbol came from
// and look for a single exact match.
+ llvm::DenseSet<SymbolFile *> searched_symbol_files;
if (sc.module_sp)
{
num_matches = sc.module_sp->FindTypes (sc,
ConstString(class_name),
exact_match,
1,
+ searched_symbol_files,
class_types);
}
-
+
// If we didn't find a symbol, then move on to the entire
// module list in the target and get as many unique matches
// as possible
if (num_matches == 0)
{
- num_matches = target->GetImages().FindTypes (sc,
- ConstString(class_name),
- exact_match,
- UINT32_MAX,
- class_types);
+ num_matches = target.GetImages().FindTypes(sc, ConstString(class_name), exact_match,
+ UINT32_MAX, searched_symbol_files, class_types);
}
-
+
lldb::TypeSP type_sp;
if (num_matches == 0)
{
if (log)
log->Printf("0x%16.16" PRIx64 ": is not dynamic\n", original_ptr);
- return false;
+ return TypeAndOrName();
}
if (num_matches == 1)
{
type_sp = class_types.GetTypeAtIndex(0);
- if (log)
- log->Printf ("0x%16.16" PRIx64 ": static-type = '%s' has dynamic type: uid={0x%" PRIx64 "}, type-name='%s'\n",
- original_ptr,
- in_value.GetTypeName().AsCString(),
- type_sp->GetID(),
- type_sp->GetName().GetCString());
-
- class_type_or_name.SetTypeSP(class_types.GetTypeAtIndex(0));
+ if (type_sp)
+ {
+ if (ClangASTContext::IsCXXClassType(type_sp->GetForwardCompilerType()))
+ {
+ if (log)
+ log->Printf("0x%16.16" PRIx64
+ ": static-type = '%s' has dynamic type: uid={0x%" PRIx64
+ "}, type-name='%s'\n",
+ original_ptr, in_value.GetTypeName().AsCString(), type_sp->GetID(),
+ type_sp->GetName().GetCString());
+ type_info.SetTypeSP(type_sp);
+ }
+ }
}
else if (num_matches > 1)
{
@@ -191,7 +158,7 @@ ItaniumABILanguageRuntime::GetDynamicTypeAndAddress (ValueObject &in_value,
type_sp = class_types.GetTypeAtIndex(i);
if (type_sp)
{
- if (ClangASTContext::IsCXXClassType(type_sp->GetFullCompilerType ()))
+ if (ClangASTContext::IsCXXClassType(type_sp->GetForwardCompilerType()))
{
if (log)
log->Printf ("0x%16.16" PRIx64 ": static-type = '%s' has multiple matching dynamic types, picking this one: uid={0x%" PRIx64 "}, type-name='%s'\n",
@@ -199,74 +166,112 @@ ItaniumABILanguageRuntime::GetDynamicTypeAndAddress (ValueObject &in_value,
in_value.GetTypeName().AsCString(),
type_sp->GetID(),
type_sp->GetName().GetCString());
- class_type_or_name.SetTypeSP(type_sp);
- break;
+ type_info.SetTypeSP(type_sp);
}
}
}
-
- if (i == num_matches)
- {
- if (log)
- log->Printf ("0x%16.16" PRIx64 ": static-type = '%s' has multiple matching dynamic types, didn't find a C++ match\n",
- original_ptr,
- in_value.GetTypeName().AsCString());
- return false;
- }
- }
-
- // There can only be one type with a given name,
- // so we've just found duplicate definitions, and this
- // one will do as well as any other.
- // We don't consider something to have a dynamic type if
- // it is the same as the static type. So compare against
- // the value we were handed.
- if (type_sp)
- {
- if (ClangASTContext::AreTypesSame (in_value.GetCompilerType(),
- type_sp->GetFullCompilerType ()))
- {
- // The dynamic type we found was the same type,
- // so we don't have a dynamic type here...
- return false;
- }
- // The offset_to_top is two pointers above the address.
- Address offset_to_top_address = address_point_address;
- int64_t slide = -2 * ((int64_t) target->GetArchitecture().GetAddressByteSize());
- offset_to_top_address.Slide (slide);
-
- Error error;
- lldb::addr_t offset_to_top_location = offset_to_top_address.GetLoadAddress(target);
-
- size_t bytes_read = process->ReadMemory (offset_to_top_location,
- memory_buffer,
- address_byte_size,
- error);
-
- if (!error.Success() || (bytes_read != address_byte_size))
- {
- return false;
- }
-
- offset = 0;
- int64_t offset_to_top = data.GetMaxS64(&offset, process->GetAddressByteSize());
-
- // So the dynamic type is a value that starts at offset_to_top
- // above the original address.
- lldb::addr_t dynamic_addr = original_ptr + offset_to_top;
- if (!target->GetSectionLoadList().ResolveLoadAddress (dynamic_addr, dynamic_address))
+ if (log && i == num_matches)
{
- dynamic_address.SetRawAddress(dynamic_addr);
+ log->Printf("0x%16.16" PRIx64 ": static-type = '%s' has multiple matching dynamic "
+ "types, didn't find a C++ match\n",
+ original_ptr, in_value.GetTypeName().AsCString());
}
- return true;
}
+ if (type_info)
+ SetDynamicTypeInfo(vtable_addr, type_info);
+ return type_info;
}
}
}
}
}
-
+ return TypeAndOrName();
+}
+
+bool
+ItaniumABILanguageRuntime::GetDynamicTypeAndAddress(ValueObject &in_value, lldb::DynamicValueType use_dynamic,
+ TypeAndOrName &class_type_or_name, Address &dynamic_address,
+ Value::ValueType &value_type)
+{
+ // For Itanium, if the type has a vtable pointer in the object, it will be at offset 0
+ // in the object. That will point to the "address point" within the vtable (not the beginning of the
+ // vtable.) We can then look up the symbol containing this "address point" and that symbol's name
+ // demangled will contain the full class name.
+ // The second pointer above the "address point" is the "offset_to_top". We'll use that to get the
+ // start of the value object which holds the dynamic type.
+ //
+
+ class_type_or_name.Clear();
+ value_type = Value::ValueType::eValueTypeScalar;
+
+ // Only a pointer or reference type can have a different dynamic and static type:
+ if (CouldHaveDynamicValue(in_value))
+ {
+ // First job, pull out the address at 0 offset from the object.
+ AddressType address_type;
+ lldb::addr_t original_ptr = in_value.GetPointerValue(&address_type);
+ if (original_ptr == LLDB_INVALID_ADDRESS)
+ return false;
+
+ ExecutionContext exe_ctx(in_value.GetExecutionContextRef());
+
+ Process *process = exe_ctx.GetProcessPtr();
+
+ if (process == nullptr)
+ return false;
+
+ Error error;
+ const lldb::addr_t vtable_address_point = process->ReadPointerFromMemory(original_ptr, error);
+
+ if (!error.Success() || vtable_address_point == LLDB_INVALID_ADDRESS)
+ {
+ return false;
+ }
+
+ class_type_or_name = GetTypeInfoFromVTableAddress(in_value, original_ptr, vtable_address_point);
+
+ if (class_type_or_name)
+ {
+ TypeSP type_sp = class_type_or_name.GetTypeSP();
+ // There can only be one type with a given name,
+ // so we've just found duplicate definitions, and this
+ // one will do as well as any other.
+ // We don't consider something to have a dynamic type if
+ // it is the same as the static type. So compare against
+ // the value we were handed.
+ if (type_sp)
+ {
+ if (ClangASTContext::AreTypesSame(in_value.GetCompilerType(), type_sp->GetForwardCompilerType()))
+ {
+ // The dynamic type we found was the same type,
+ // so we don't have a dynamic type here...
+ return false;
+ }
+
+ // The offset_to_top is two pointers above the vtable pointer.
+ const uint32_t addr_byte_size = process->GetAddressByteSize();
+ const lldb::addr_t offset_to_top_location = vtable_address_point - 2 * addr_byte_size;
+ // Watch for underflow, offset_to_top_location should be less than vtable_address_point
+ if (offset_to_top_location >= vtable_address_point)
+ return false;
+ const int64_t offset_to_top =
+ process->ReadSignedIntegerFromMemory(offset_to_top_location, addr_byte_size, INT64_MIN, error);
+
+ if (offset_to_top == INT64_MIN)
+ return false;
+ // So the dynamic type is a value that starts at offset_to_top
+ // above the original address.
+ lldb::addr_t dynamic_addr = original_ptr + offset_to_top;
+ if (!process->GetTarget().GetSectionLoadList().ResolveLoadAddress(dynamic_addr, dynamic_address))
+ {
+ dynamic_address.SetRawAddress(dynamic_addr);
+ }
+ return true;
+ }
+ }
+ }
+
return class_type_or_name.IsEmpty() == false;
}
@@ -336,12 +341,94 @@ ItaniumABILanguageRuntime::CreateInstance (Process *process, lldb::LanguageType
return NULL;
}
+class CommandObjectMultiwordItaniumABI_Demangle : public CommandObjectParsed
+{
+public:
+ CommandObjectMultiwordItaniumABI_Demangle (CommandInterpreter &interpreter) :
+ CommandObjectParsed (interpreter,
+ "demangle",
+ "Demangle a C++ mangled name.",
+ "language cplusplus demangle")
+ {
+ CommandArgumentEntry arg;
+ CommandArgumentData index_arg;
+
+ // Define the first (and only) variant of this arg.
+ index_arg.arg_type = eArgTypeSymbol;
+ index_arg.arg_repetition = eArgRepeatPlus;
+
+ // There is only one variant this argument could be; put it into the argument entry.
+ arg.push_back (index_arg);
+
+ // Push the data for the first argument into the m_arguments vector.
+ m_arguments.push_back (arg);
+ }
+
+ ~CommandObjectMultiwordItaniumABI_Demangle() override = default;
+
+protected:
+ bool
+ DoExecute(Args& command, CommandReturnObject &result) override
+ {
+ bool demangled_any = false;
+ bool error_any = false;
+ for (size_t i = 0; i < command.GetArgumentCount(); i++)
+ {
+ auto arg = command.GetArgumentAtIndex(i);
+ if (arg && *arg)
+ {
+ ConstString mangled_cs(arg);
+
+ // the actual Mangled class should be strict about this, but on the command line
+ // if you're copying mangled names out of 'nm' on Darwin, they will come out with
+ // an extra underscore - be willing to strip this on behalf of the user
+ // This is the moral equivalent of the -_/-n options to c++filt
+ if (mangled_cs.GetStringRef().startswith("__Z"))
+ mangled_cs.SetCString(arg+1);
+
+ Mangled mangled(mangled_cs, true);
+ if (mangled.GuessLanguage() == lldb::eLanguageTypeC_plus_plus)
+ {
+ ConstString demangled(mangled.GetDisplayDemangledName(lldb::eLanguageTypeC_plus_plus));
+ demangled_any = true;
+ result.AppendMessageWithFormat("%s ---> %s\n", arg, demangled.GetCString());
+ }
+ else
+ {
+ error_any = true;
+ result.AppendErrorWithFormat("%s is not a valid C++ mangled name\n", arg);
+ }
+ }
+ }
+
+ result.SetStatus(error_any ? lldb::eReturnStatusFailed :
+ (demangled_any ? lldb::eReturnStatusSuccessFinishResult : lldb::eReturnStatusSuccessFinishNoResult));
+ return result.Succeeded();
+ }
+};
+
+class CommandObjectMultiwordItaniumABI : public CommandObjectMultiword
+{
+public:
+ CommandObjectMultiwordItaniumABI(CommandInterpreter &interpreter)
+ : CommandObjectMultiword(interpreter, "cplusplus", "Commands for operating on the C++ language runtime.",
+ "cplusplus <subcommand> [<subcommand-options>]")
+ {
+ LoadSubCommand ("demangle", CommandObjectSP (new CommandObjectMultiwordItaniumABI_Demangle (interpreter)));
+ }
+
+ ~CommandObjectMultiwordItaniumABI() override = default;
+};
+
void
ItaniumABILanguageRuntime::Initialize()
{
PluginManager::RegisterPlugin (GetPluginNameStatic(),
"Itanium ABI for the C++ language",
- CreateInstance);
+ CreateInstance,
+ [] (CommandInterpreter& interpreter) -> lldb::CommandObjectSP {
+ return CommandObjectSP(new CommandObjectMultiwordItaniumABI(interpreter));
+ });
}
void
@@ -408,6 +495,7 @@ ItaniumABILanguageRuntime::CreateExceptionResolver (Breakpoint *bkpt, bool catch
exception_names.size(),
eFunctionNameTypeBase,
eLanguageTypeUnknown,
+ 0,
eLazyBoolNo));
return resolver_sp;
@@ -510,3 +598,21 @@ ItaniumABILanguageRuntime::ExceptionBreakpointsExplainStop (lldb::StopInfoSP sto
m_cxx_exception_bp_sp->GetID());
}
+
+TypeAndOrName
+ItaniumABILanguageRuntime::GetDynamicTypeInfo(const lldb_private::Address &vtable_addr)
+{
+ std::lock_guard<std::mutex> locker(m_dynamic_type_map_mutex);
+ DynamicTypeCache::const_iterator pos = m_dynamic_type_map.find(vtable_addr);
+ if (pos == m_dynamic_type_map.end())
+ return TypeAndOrName();
+ else
+ return pos->second;
+}
+
+void
+ItaniumABILanguageRuntime::SetDynamicTypeInfo(const lldb_private::Address &vtable_addr, const TypeAndOrName &type_info)
+{
+ std::lock_guard<std::mutex> locker(m_dynamic_type_map_mutex);
+ m_dynamic_type_map[vtable_addr] = type_info;
+}
diff --git a/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.h b/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.h
index c06b9863a9bf..86bd728d6c6f 100644
--- a/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.h
+++ b/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.h
@@ -12,12 +12,15 @@
// C Includes
// C++ Includes
+#include <map>
+#include <mutex>
#include <vector>
// Other libraries and framework includes
// Project includes
#include "lldb/lldb-private.h"
#include "lldb/Breakpoint/BreakpointResolver.h"
+#include "lldb/Symbol/Type.h"
#include "lldb/Target/LanguageRuntime.h"
#include "lldb/Target/CPPLanguageRuntime.h"
#include "lldb/Core/Value.h"
@@ -100,9 +103,29 @@ namespace lldb_private {
bool is_internal);
private:
- ItaniumABILanguageRuntime(Process *process) : lldb_private::CPPLanguageRuntime(process) { } // Call CreateInstance instead.
-
- lldb::BreakpointSP m_cxx_exception_bp_sp;
+ typedef std::map<lldb_private::Address, TypeAndOrName> DynamicTypeCache;
+
+ ItaniumABILanguageRuntime(Process *process)
+ : // Call CreateInstance instead.
+ lldb_private::CPPLanguageRuntime(process),
+ m_cxx_exception_bp_sp(),
+ m_dynamic_type_map(),
+ m_dynamic_type_map_mutex()
+ {
+ }
+
+ lldb::BreakpointSP m_cxx_exception_bp_sp;
+ DynamicTypeCache m_dynamic_type_map;
+ std::mutex m_dynamic_type_map_mutex;
+
+ TypeAndOrName
+ GetTypeInfoFromVTableAddress(ValueObject &in_value, lldb::addr_t original_ptr, lldb::addr_t vtable_addr);
+
+ TypeAndOrName
+ GetDynamicTypeInfo(const lldb_private::Address &vtable_addr);
+
+ void
+ SetDynamicTypeInfo(const lldb_private::Address &vtable_addr, const TypeAndOrName &type_info);
};
} // namespace lldb_private
diff --git a/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/Makefile b/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/Makefile
deleted file mode 100644
index ac87437f9d2a..000000000000
--- a/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/Makefile
+++ /dev/null
@@ -1,14 +0,0 @@
-##===- source/Plugins/LangRuntime/C++/ItaniumABI/Makefile --*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LLDB_LEVEL := ../../../../..
-LIBRARYNAME := lldbPluginCXXItaniumABI
-BUILD_ARCHIVE = 1
-
-include $(LLDB_LEVEL)/Makefile
diff --git a/source/Plugins/LanguageRuntime/Go/GoLanguageRuntime.cpp b/source/Plugins/LanguageRuntime/Go/GoLanguageRuntime.cpp
index d59f292e7a08..c752971e7a09 100644
--- a/source/Plugins/LanguageRuntime/Go/GoLanguageRuntime.cpp
+++ b/source/Plugins/LanguageRuntime/Go/GoLanguageRuntime.cpp
@@ -20,6 +20,7 @@
#include "lldb/Core/ValueObjectMemory.h"
#include "lldb/Symbol/GoASTContext.h"
#include "lldb/Symbol/Symbol.h"
+#include "lldb/Symbol/SymbolFile.h"
#include "lldb/Symbol/TypeList.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/RegisterContext.h"
@@ -117,10 +118,12 @@ LookupRuntimeType(ValueObjectSP type, ExecutionContext* exe_ctx, bool* is_direct
SymbolContext sc;
TypeList type_list;
+ llvm::DenseSet<SymbolFile *> searched_symbol_files;
uint32_t num_matches = target->GetImages().FindTypes (sc,
const_typename,
false,
2,
+ searched_symbol_files,
type_list);
if (num_matches > 0) {
return type_list.GetTypeAtIndex(0)->GetFullCompilerType();
diff --git a/source/Plugins/LanguageRuntime/Go/Makefile b/source/Plugins/LanguageRuntime/Go/Makefile
deleted file mode 100644
index 1c8114e421c1..000000000000
--- a/source/Plugins/LanguageRuntime/Go/Makefile
+++ /dev/null
@@ -1,14 +0,0 @@
-##===- Source/Plugins/LangRuntime/Go/Makefile ----*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LLDB_LEVEL := ../../../..
-LIBRARYNAME := lldbPluginLanguageRuntimeGo
-BUILD_ARCHIVE = 1
-
-include $(LLDB_LEVEL)/Makefile
diff --git a/source/Plugins/LanguageRuntime/Java/CMakeLists.txt b/source/Plugins/LanguageRuntime/Java/CMakeLists.txt
new file mode 100644
index 000000000000..4cfd71c2e242
--- /dev/null
+++ b/source/Plugins/LanguageRuntime/Java/CMakeLists.txt
@@ -0,0 +1,3 @@
+add_lldb_library(lldbPluginLanguageRuntimeJava
+ JavaLanguageRuntime.cpp
+ )
diff --git a/source/Plugins/LanguageRuntime/Java/JavaLanguageRuntime.cpp b/source/Plugins/LanguageRuntime/Java/JavaLanguageRuntime.cpp
new file mode 100644
index 000000000000..07312a8af0d6
--- /dev/null
+++ b/source/Plugins/LanguageRuntime/Java/JavaLanguageRuntime.cpp
@@ -0,0 +1,176 @@
+//===-- JavaLanguageRuntime.cpp ---------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "JavaLanguageRuntime.h"
+
+#include "lldb/Core/PluginManager.h"
+#include "lldb/Symbol/JavaASTContext.h"
+#include "lldb/Symbol/Symbol.h"
+#include "lldb/Symbol/SymbolContext.h"
+#include "lldb/Symbol/SymbolFile.h"
+#include "lldb/Symbol/Type.h"
+#include "lldb/Symbol/TypeList.h"
+#include "lldb/Target/SectionLoadList.h"
+#include "lldb/Target/Target.h"
+#include "llvm/ADT/StringRef.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+JavaLanguageRuntime::JavaLanguageRuntime(Process *process) : LanguageRuntime(process)
+{
+}
+
+LanguageRuntime *
+JavaLanguageRuntime::CreateInstance(Process *process, lldb::LanguageType language)
+{
+ if (language == eLanguageTypeJava)
+ return new JavaLanguageRuntime(process);
+ return nullptr;
+}
+
+void
+JavaLanguageRuntime::Initialize()
+{
+ PluginManager::RegisterPlugin(GetPluginNameStatic(), "Java language runtime", CreateInstance);
+}
+
+void
+JavaLanguageRuntime::Terminate()
+{
+ PluginManager::UnregisterPlugin(CreateInstance);
+}
+
+lldb_private::ConstString
+JavaLanguageRuntime::GetPluginNameStatic()
+{
+ static ConstString g_name("java");
+ return g_name;
+}
+
+lldb_private::ConstString
+JavaLanguageRuntime::GetPluginName()
+{
+ return GetPluginNameStatic();
+}
+
+uint32_t
+JavaLanguageRuntime::GetPluginVersion()
+{
+ return 1;
+}
+
+bool
+JavaLanguageRuntime::CouldHaveDynamicValue(ValueObject &in_value)
+{
+ return true;
+}
+
+static ConstString
+GetDynamicTypeId(ExecutionContext *exe_ctx, Target *target, ValueObject &in_value)
+{
+ SymbolContext sc;
+ TypeList class_types;
+ llvm::DenseSet<SymbolFile *> searched_symbol_files;
+ size_t num_matches = target->GetImages().FindTypes(sc, ConstString("Object"),
+ true, // name_is_fully_qualified
+ UINT32_MAX, searched_symbol_files, class_types);
+ for (size_t i = 0; i < num_matches; ++i)
+ {
+ TypeSP type_sp = class_types.GetTypeAtIndex(i);
+ CompilerType compiler_type = type_sp->GetFullCompilerType();
+
+ if (compiler_type.GetMinimumLanguage() != eLanguageTypeJava ||
+ compiler_type.GetTypeName() != ConstString("java::lang::Object"))
+ continue;
+
+ if (compiler_type.GetCompleteType() && compiler_type.IsCompleteType())
+ {
+ uint64_t type_id = JavaASTContext::CalculateDynamicTypeId(exe_ctx, compiler_type, in_value);
+ if (type_id != UINT64_MAX)
+ {
+ char id[32];
+ snprintf(id, sizeof(id), "0x%" PRIX64, type_id);
+ return ConstString(id);
+ }
+ }
+ }
+ return ConstString();
+}
+
+bool
+JavaLanguageRuntime::GetDynamicTypeAndAddress(ValueObject &in_value, lldb::DynamicValueType use_dynamic,
+ TypeAndOrName &class_type_or_name, Address &dynamic_address,
+ Value::ValueType &value_type)
+{
+ class_type_or_name.Clear();
+
+ // null references don't have a dynamic type
+ if (in_value.IsNilReference())
+ return false;
+
+ ExecutionContext exe_ctx(in_value.GetExecutionContextRef());
+ Target *target = exe_ctx.GetTargetPtr();
+ if (!target)
+ return false;
+
+ ConstString linkage_name;
+ CompilerType in_type = in_value.GetCompilerType();
+ if (in_type.IsPossibleDynamicType(nullptr, false, false))
+ linkage_name = GetDynamicTypeId(&exe_ctx, target, in_value);
+ else
+ linkage_name = JavaASTContext::GetLinkageName(in_type);
+
+ if (!linkage_name)
+ return false;
+
+ class_type_or_name.SetName(in_type.GetNonReferenceType().GetTypeName());
+
+ SymbolContext sc;
+ TypeList class_types;
+ llvm::DenseSet<SymbolFile *> searched_symbol_files;
+ size_t num_matches = target->GetImages().FindTypes(sc, linkage_name,
+ true, // name_is_fully_qualified
+ UINT32_MAX, searched_symbol_files, class_types);
+
+ for (size_t i = 0; i < num_matches; ++i)
+ {
+ TypeSP type_sp = class_types.GetTypeAtIndex(i);
+ CompilerType compiler_type = type_sp->GetFullCompilerType();
+
+ if (compiler_type.GetMinimumLanguage() != eLanguageTypeJava)
+ continue;
+
+ if (compiler_type.GetCompleteType() && compiler_type.IsCompleteType())
+ {
+ class_type_or_name.SetTypeSP(type_sp);
+
+ Value &value = in_value.GetValue();
+ value_type = value.GetValueType();
+ dynamic_address.SetRawAddress(value.GetScalar().ULongLong(0));
+ return true;
+ }
+ }
+ return false;
+}
+
+TypeAndOrName
+JavaLanguageRuntime::FixUpDynamicType(const TypeAndOrName &type_and_or_name, ValueObject &static_value)
+{
+ CompilerType static_type(static_value.GetCompilerType());
+
+ TypeAndOrName ret(type_and_or_name);
+ if (type_and_or_name.HasType())
+ {
+ CompilerType orig_type = type_and_or_name.GetCompilerType();
+ if (static_type.IsReferenceType())
+ ret.SetCompilerType(orig_type.GetLValueReferenceType());
+ }
+ return ret;
+}
diff --git a/source/Plugins/LanguageRuntime/Java/JavaLanguageRuntime.h b/source/Plugins/LanguageRuntime/Java/JavaLanguageRuntime.h
new file mode 100644
index 000000000000..83ed35dbb59d
--- /dev/null
+++ b/source/Plugins/LanguageRuntime/Java/JavaLanguageRuntime.h
@@ -0,0 +1,90 @@
+//===-- JavaLanguageRuntime.h -----------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_JavaLanguageRuntime_h_
+#define liblldb_JavaLanguageRuntime_h_
+
+// C Includes
+// C++ Includes
+#include <vector>
+// Other libraries and framework includes
+// Project includes
+#include "lldb/Core/PluginInterface.h"
+#include "lldb/Target/LanguageRuntime.h"
+#include "lldb/lldb-private.h"
+
+namespace lldb_private
+{
+
+class JavaLanguageRuntime : public LanguageRuntime
+{
+public:
+ static void
+ Initialize();
+
+ static void
+ Terminate();
+
+ static lldb_private::LanguageRuntime *
+ CreateInstance(Process *process, lldb::LanguageType language);
+
+ static lldb_private::ConstString
+ GetPluginNameStatic();
+
+ lldb_private::ConstString
+ GetPluginName() override;
+
+ uint32_t
+ GetPluginVersion() override;
+
+ lldb::LanguageType
+ GetLanguageType() const override
+ {
+ return lldb::eLanguageTypeJava;
+ }
+
+ bool
+ GetObjectDescription(Stream &str, ValueObject &object) override
+ {
+ return false;
+ }
+
+ bool
+ GetObjectDescription(Stream &str, Value &value, ExecutionContextScope *exe_scope) override
+ {
+ return false;
+ }
+
+ lldb::BreakpointResolverSP
+ CreateExceptionResolver(Breakpoint *bkpt, bool catch_bp, bool throw_bp) override
+ {
+ return nullptr;
+ }
+
+ TypeAndOrName
+ FixUpDynamicType(const TypeAndOrName &type_and_or_name, ValueObject &static_value) override;
+
+ bool
+ CouldHaveDynamicValue(ValueObject &in_value) override;
+
+ bool
+ GetDynamicTypeAndAddress(ValueObject &in_value, lldb::DynamicValueType use_dynamic,
+ TypeAndOrName &class_type_or_name, Address &address,
+ Value::ValueType &value_type) override;
+
+protected:
+ JavaLanguageRuntime(Process *process);
+
+private:
+ DISALLOW_COPY_AND_ASSIGN(JavaLanguageRuntime);
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_JavaLanguageRuntime_h_
diff --git a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.cpp b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.cpp
index 711d324d8aa7..5cf99a573d86 100644
--- a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.cpp
+++ b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.cpp
@@ -499,11 +499,9 @@ ClassDescriptorV2::GetInstanceSize ()
return 0;
}
-ClassDescriptorV2::iVarsStorage::iVarsStorage ():
-m_filled(false),
-m_ivars(),
-m_mutex(Mutex::eMutexTypeRecursive)
-{}
+ClassDescriptorV2::iVarsStorage::iVarsStorage() : m_filled(false), m_ivars(), m_mutex()
+{
+}
size_t
ClassDescriptorV2::iVarsStorage::size ()
@@ -522,7 +520,7 @@ ClassDescriptorV2::iVarsStorage::fill (AppleObjCRuntimeV2& runtime, ClassDescrip
{
if (m_filled)
return;
- Mutex::Locker lock(m_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_TYPES | LIBLLDB_LOG_VERBOSE));
if (log)
log->Printf("[ClassDescriptorV2::iVarsStorage::fill] class_name = %s", descriptor.GetClassName().AsCString("<unknown"));
diff --git a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.h b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.h
index 18591ecd6e93..f5fc8bc0644b 100644
--- a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.h
+++ b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.h
@@ -12,10 +12,11 @@
// C Includes
// C++ Includes
+#include <mutex>
+
// Other libraries and framework includes
// Project includes
#include "lldb/lldb-private.h"
-#include "lldb/Host/Mutex.h"
#include "lldb/Target/ObjCLanguageRuntime.h"
#include "AppleObjCRuntimeV2.h"
@@ -247,7 +248,7 @@ private:
private:
bool m_filled;
std::vector<iVarDescriptor> m_ivars;
- Mutex m_mutex;
+ std::recursive_mutex m_mutex;
};
// The constructor should only be invoked by the runtime as it builds its caches
diff --git a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.cpp b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.cpp
index cd6ece297ed1..0c0e4f1ce8cc 100644
--- a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.cpp
+++ b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.cpp
@@ -9,10 +9,11 @@
#include "AppleObjCDeclVendor.h"
+#include "Plugins/ExpressionParser/Clang/ASTDumper.h"
#include "lldb/Core/Log.h"
#include "lldb/Core/Module.h"
-#include "Plugins/ExpressionParser/Clang/ASTDumper.h"
#include "lldb/Symbol/ClangExternalASTSourceCommon.h"
+#include "lldb/Symbol/ClangUtil.h"
#include "lldb/Target/ObjCLanguageRuntime.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/Target.h"
@@ -356,9 +357,10 @@ public:
}
clang::Selector sel = ast_ctx.Selectors.getSelector(is_zero_argument ? 0 : selector_components.size(), selector_components.data());
-
- clang::QualType ret_type = ClangASTContext::GetQualType(type_realizer_sp->RealizeType(interface_decl->getASTContext(), m_type_vector[0].c_str(), for_expression));
-
+
+ clang::QualType ret_type = ClangUtil::GetQualType(
+ type_realizer_sp->RealizeType(interface_decl->getASTContext(), m_type_vector[0].c_str(), for_expression));
+
if (ret_type.isNull())
return NULL;
@@ -384,8 +386,9 @@ public:
++ai)
{
const bool for_expression = true;
- clang::QualType arg_type = ClangASTContext::GetQualType(type_realizer_sp->RealizeType(ast_ctx, m_type_vector[ai].c_str(), for_expression));
-
+ clang::QualType arg_type = ClangUtil::GetQualType(
+ type_realizer_sp->RealizeType(ast_ctx, m_type_vector[ai].c_str(), for_expression));
+
if (arg_type.isNull())
return NULL; // well, we just wasted a bunch of time. Wish we could delete the stuff we'd just made!
@@ -404,6 +407,24 @@ public:
return ret;
}
+
+ explicit operator bool ()
+ {
+ return m_is_valid;
+ }
+
+ size_t
+ GetNumTypes ()
+ {
+ return m_type_vector.size();
+ }
+
+ const char*
+ GetTypeAtIndex (size_t idx)
+ {
+ return m_type_vector[idx].c_str();
+ }
+
private:
typedef std::vector <std::string> TypeVector;
@@ -502,17 +523,12 @@ AppleObjCDeclVendor::FinishDecl(clang::ObjCInterfaceDecl *interface_decl)
{
clang::TypeSourceInfo * const type_source_info = nullptr;
const bool is_synthesized = false;
- clang::ObjCIvarDecl *ivar_decl = clang::ObjCIvarDecl::Create (*m_ast_ctx.getASTContext(),
- interface_decl,
- clang::SourceLocation(),
- clang::SourceLocation(),
- &m_ast_ctx.getASTContext()->Idents.get(name),
- ClangASTContext::GetQualType(ivar_type),
- type_source_info, // TypeSourceInfo *
- clang::ObjCIvarDecl::Public,
- 0,
- is_synthesized);
-
+ clang::ObjCIvarDecl *ivar_decl = clang::ObjCIvarDecl::Create(
+ *m_ast_ctx.getASTContext(), interface_decl, clang::SourceLocation(), clang::SourceLocation(),
+ &m_ast_ctx.getASTContext()->Idents.get(name), ClangUtil::GetQualType(ivar_type),
+ type_source_info, // TypeSourceInfo *
+ clang::ObjCIvarDecl::Public, 0, is_synthesized);
+
if (ivar_decl)
{
interface_decl->addDecl(ivar_decl);
diff --git a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp
index 2810b24cb7a4..6d83f7a7c5e1 100644
--- a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp
+++ b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp
@@ -23,6 +23,7 @@
#include "lldb/Core/Section.h"
#include "lldb/Core/StreamString.h"
#include "lldb/Core/ValueObject.h"
+#include "lldb/Expression/DiagnosticManager.h"
#include "lldb/Expression/FunctionCaller.h"
#include "lldb/Symbol/ClangASTContext.h"
#include "lldb/Symbol/ObjectFile.h"
@@ -151,10 +152,10 @@ AppleObjCRuntime::GetObjectDescription (Stream &strm, Value &value, ExecutionCon
exe_ctx.SetFrameSP(thread->GetSelectedFrame());
}
}
-
+
// Now we're ready to call the function:
-
- StreamString error_stream;
+
+ DiagnosticManager diagnostics;
lldb::addr_t wrapper_struct_addr = LLDB_INVALID_ADDRESS;
if (!m_print_object_caller_up)
@@ -172,30 +173,22 @@ AppleObjCRuntime::GetObjectDescription (Stream &strm, Value &value, ExecutionCon
strm.Printf("Could not get function runner to call print for debugger function: %s.", error.AsCString());
return false;
}
- m_print_object_caller_up->InsertFunction(exe_ctx, wrapper_struct_addr, error_stream);
+ m_print_object_caller_up->InsertFunction(exe_ctx, wrapper_struct_addr, diagnostics);
}
else
{
- m_print_object_caller_up->WriteFunctionArguments(exe_ctx,
- wrapper_struct_addr,
- arg_value_list,
- error_stream);
+ m_print_object_caller_up->WriteFunctionArguments(exe_ctx, wrapper_struct_addr, arg_value_list, diagnostics);
}
-
-
EvaluateExpressionOptions options;
options.SetUnwindOnError(true);
options.SetTryAllThreads(true);
options.SetStopOthers(true);
options.SetIgnoreBreakpoints(true);
options.SetTimeoutUsec(PO_FUNCTION_TIMEOUT_USEC);
-
- ExpressionResults results = m_print_object_caller_up->ExecuteFunction (exe_ctx,
- &wrapper_struct_addr,
- options,
- error_stream,
- ret);
+
+ ExpressionResults results =
+ m_print_object_caller_up->ExecuteFunction(exe_ctx, &wrapper_struct_addr, options, diagnostics, ret);
if (results != eExpressionCompleted)
{
strm.Printf("Error evaluating Print Object function: %d.\n", results);
@@ -401,8 +394,8 @@ AppleObjCRuntime::GetObjCVersion (Process *process, ModuleSP &objc_module_sp)
return ObjCRuntimeVersions::eObjC_VersionUnknown;
const ModuleList &target_modules = target.GetImages();
- Mutex::Locker modules_locker(target_modules.GetMutex());
-
+ std::lock_guard<std::recursive_mutex> gaurd(target_modules.GetMutex());
+
size_t num_images = target_modules.GetSize();
for (size_t i = 0; i < num_images; i++)
{
@@ -531,7 +524,7 @@ AppleObjCRuntime::ReadObjCLibraryIfNeeded (const ModuleList &module_list)
{
if (!HasReadObjCLibrary ())
{
- Mutex::Locker locker (module_list.GetMutex ());
+ std::lock_guard<std::recursive_mutex> guard(module_list.GetMutex());
size_t num_modules = module_list.GetSize();
for (size_t i = 0; i < num_modules; i++)
diff --git a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp
index 59b28b63f6b3..805fca7a31b9 100644
--- a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp
+++ b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp
@@ -136,6 +136,7 @@ AppleObjCRuntimeV1::CreateExceptionResolver (Breakpoint *bkpt, bool catch_bp, bo
eFunctionNameTypeBase,
eLanguageTypeUnknown,
Breakpoint::Exact,
+ 0,
eLazyBoolNo));
// FIXME: don't do catch yet.
return resolver_sp;
diff --git a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp
index 584449430829..e9a799bb3651 100644
--- a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp
+++ b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp
@@ -36,12 +36,14 @@
#include "lldb/Core/StreamString.h"
#include "lldb/Core/Timer.h"
#include "lldb/Core/ValueObjectVariable.h"
+#include "lldb/Expression/DiagnosticManager.h"
#include "lldb/Expression/FunctionCaller.h"
#include "lldb/Expression/UtilityFunction.h"
#include "lldb/Host/StringConvert.h"
#include "lldb/Interpreter/CommandObject.h"
#include "lldb/Interpreter/CommandObjectMultiword.h"
#include "lldb/Interpreter/CommandReturnObject.h"
+#include "lldb/Interpreter/OptionValueBoolean.h"
#include "lldb/Symbol/ClangASTContext.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Symbol/Symbol.h"
@@ -60,9 +62,6 @@
#include "AppleObjCDeclVendor.h"
#include "AppleObjCTrampolineHandler.h"
-#if defined(__APPLE__)
-#include "Plugins/Platform/MacOSX/PlatformiOSSimulator.h"
-#endif
using namespace lldb;
using namespace lldb_private;
@@ -81,12 +80,7 @@ extern "C"
char *strncpy (char * s1, const char * s2, size_t n);
int printf(const char * format, ...);
}
-//#define ENABLE_DEBUG_PRINTF // COMMENT THIS LINE OUT PRIOR TO CHECKIN
-#ifdef ENABLE_DEBUG_PRINTF
-#define DEBUG_PRINTF(fmt, ...) printf(fmt, ## __VA_ARGS__)
-#else
-#define DEBUG_PRINTF(fmt, ...)
-#endif
+#define DEBUG_PRINTF(fmt, ...) if (should_log) printf(fmt, ## __VA_ARGS__)
typedef struct _NXMapTable {
void *prototype;
@@ -112,7 +106,8 @@ struct ClassInfo
uint32_t
__lldb_apple_objc_v2_get_dynamic_class_info (void *gdb_objc_realized_classes_ptr,
void *class_infos_ptr,
- uint32_t class_infos_byte_size)
+ uint32_t class_infos_byte_size,
+ uint32_t should_log)
{
DEBUG_PRINTF ("gdb_objc_realized_classes_ptr = %p\n", gdb_objc_realized_classes_ptr);
DEBUG_PRINTF ("class_infos_ptr = %p\n", class_infos_ptr);
@@ -170,12 +165,7 @@ extern "C"
int printf(const char * format, ...);
}
-// #define ENABLE_DEBUG_PRINTF // COMMENT THIS LINE OUT PRIOR TO CHECKIN
-#ifdef ENABLE_DEBUG_PRINTF
-#define DEBUG_PRINTF(fmt, ...) printf(fmt, ## __VA_ARGS__)
-#else
-#define DEBUG_PRINTF(fmt, ...)
-#endif
+#define DEBUG_PRINTF(fmt, ...) if (should_log) printf(fmt, ## __VA_ARGS__)
struct objc_classheader_t {
@@ -224,12 +214,13 @@ struct ClassInfo
uint32_t
__lldb_apple_objc_v2_get_shared_cache_class_info (void *objc_opt_ro_ptr,
void *class_infos_ptr,
- uint32_t class_infos_byte_size)
+ uint32_t class_infos_byte_size,
+ uint32_t should_log)
{
uint32_t idx = 0;
DEBUG_PRINTF ("objc_opt_ro_ptr = %p\n", objc_opt_ro_ptr);
DEBUG_PRINTF ("class_infos_ptr = %p\n", class_infos_ptr);
- DEBUG_PRINTF ("class_infos_byte_size = %u (%" PRIu64 " class infos)\n", class_infos_byte_size, (size_t)(class_infos_byte_size/sizeof(ClassInfo)));
+ DEBUG_PRINTF ("class_infos_byte_size = %u (%llu class infos)\n", class_infos_byte_size, (uint64_t)(class_infos_byte_size/sizeof(ClassInfo)));
if (objc_opt_ro_ptr)
{
const objc_opt_t *objc_opt = (objc_opt_t *)objc_opt_ro_ptr;
@@ -250,7 +241,7 @@ __lldb_apple_objc_v2_get_shared_cache_class_info (void *objc_opt_ro_ptr,
DEBUG_PRINTF ("objc_opt->headeropt_offset = %d\n", objc_opt->headeropt_offset);
DEBUG_PRINTF ("objc_opt->clsopt_offset = %d\n", objc_opt->clsopt_offset);
}
- if (objc_opt->version == 12 || objc_opt->version == 13 || objc_opt->version == 14)
+ if (objc_opt->version == 12 || objc_opt->version == 13 || objc_opt->version == 14 || objc_opt->version == 15)
{
const objc_clsopt_t* clsopt = NULL;
if (is_v14_format)
@@ -258,6 +249,7 @@ __lldb_apple_objc_v2_get_shared_cache_class_info (void *objc_opt_ro_ptr,
else
clsopt = (const objc_clsopt_t*)((uint8_t *)objc_opt + objc_opt->clsopt_offset);
const size_t max_class_infos = class_infos_byte_size/sizeof(ClassInfo);
+ DEBUG_PRINTF("max_class_infos = %llu\n", (uint64_t)max_class_infos);
ClassInfo *class_infos = (ClassInfo *)class_infos_ptr;
int32_t invalidEntryOffset = 0;
// this is safe to do because the version field order is invariant
@@ -269,13 +261,21 @@ __lldb_apple_objc_v2_get_shared_cache_class_info (void *objc_opt_ro_ptr,
DEBUG_PRINTF ("clsopt->capacity = %u\n", clsopt->capacity);
DEBUG_PRINTF ("clsopt->mask = 0x%8.8x\n", clsopt->mask);
DEBUG_PRINTF ("classOffsets = %p\n", classOffsets);
+ DEBUG_PRINTF("invalidEntryOffset = %d\n", invalidEntryOffset);
for (uint32_t i=0; i<clsopt->capacity; ++i)
{
const int32_t clsOffset = classOffsets[i].clsOffset;
+ DEBUG_PRINTF("clsOffset[%u] = %u\n", i, clsOffset);
if (clsOffset & 1)
+ {
+ DEBUG_PRINTF("clsOffset & 1\n");
continue; // duplicate
+ }
else if (clsOffset == invalidEntryOffset)
+ {
+ DEBUG_PRINTF("clsOffset == invalidEntryOffset\n");
continue; // invalid offset
+ }
if (class_infos && idx < max_class_infos)
{
@@ -289,6 +289,10 @@ __lldb_apple_objc_v2_get_shared_cache_class_info (void *objc_opt_ro_ptr,
h = ((h << 5) + h) + c;
class_infos[idx].hash = h;
}
+ else
+ {
+ DEBUG_PRINTF("not(class_infos && idx < max_class_infos)\n");
+ }
++idx;
}
@@ -375,27 +379,27 @@ ExtractRuntimeGlobalSymbol (Process* process,
}
}
-AppleObjCRuntimeV2::AppleObjCRuntimeV2 (Process *process,
- const ModuleSP &objc_module_sp) :
- AppleObjCRuntime (process),
- m_get_class_info_code(),
- m_get_class_info_args (LLDB_INVALID_ADDRESS),
- m_get_class_info_args_mutex (Mutex::eMutexTypeNormal),
- m_get_shared_cache_class_info_code(),
- m_get_shared_cache_class_info_args (LLDB_INVALID_ADDRESS),
- m_get_shared_cache_class_info_args_mutex (Mutex::eMutexTypeNormal),
- m_decl_vendor_ap (),
- m_isa_hash_table_ptr (LLDB_INVALID_ADDRESS),
- m_hash_signature (),
- m_has_object_getClass (false),
- m_loaded_objc_opt (false),
- m_non_pointer_isa_cache_ap(NonPointerISACache::CreateInstance(*this,objc_module_sp)),
- m_tagged_pointer_vendor_ap(TaggedPointerVendorV2::CreateInstance(*this,objc_module_sp)),
- m_encoding_to_type_sp(),
- m_noclasses_warning_emitted(false)
+AppleObjCRuntimeV2::AppleObjCRuntimeV2(Process *process, const ModuleSP &objc_module_sp)
+ : AppleObjCRuntime(process),
+ m_get_class_info_code(),
+ m_get_class_info_args(LLDB_INVALID_ADDRESS),
+ m_get_class_info_args_mutex(),
+ m_get_shared_cache_class_info_code(),
+ m_get_shared_cache_class_info_args(LLDB_INVALID_ADDRESS),
+ m_get_shared_cache_class_info_args_mutex(),
+ m_decl_vendor_ap(),
+ m_isa_hash_table_ptr(LLDB_INVALID_ADDRESS),
+ m_hash_signature(),
+ m_has_object_getClass(false),
+ m_loaded_objc_opt(false),
+ m_non_pointer_isa_cache_ap(NonPointerISACache::CreateInstance(*this, objc_module_sp)),
+ m_tagged_pointer_vendor_ap(TaggedPointerVendorV2::CreateInstance(*this, objc_module_sp)),
+ m_encoding_to_type_sp(),
+ m_noclasses_warning_emitted(false)
{
static const ConstString g_gdb_object_getClass("gdb_object_getClass");
- m_has_object_getClass = (objc_module_sp->FindFirstSymbolWithNameAndType(g_gdb_object_getClass, eSymbolTypeCode) != NULL);
+ m_has_object_getClass =
+ (objc_module_sp->FindFirstSymbolWithNameAndType(g_gdb_object_getClass, eSymbolTypeCode) != NULL);
}
bool
@@ -485,6 +489,52 @@ AppleObjCRuntimeV2::CreateInstance (Process *process, LanguageType language)
class CommandObjectObjC_ClassTable_Dump : public CommandObjectParsed
{
public:
+ class CommandOptions : public Options
+ {
+ public:
+ CommandOptions (CommandInterpreter &interpreter) :
+ Options(interpreter),
+ m_verbose(false,false)
+ {}
+
+ ~CommandOptions() override = default;
+
+ Error
+ SetOptionValue(uint32_t option_idx, const char *option_arg) override
+ {
+ Error error;
+ const int short_option = m_getopt_table[option_idx].val;
+ switch (short_option)
+ {
+ case 'v':
+ m_verbose.SetCurrentValue(true);
+ m_verbose.SetOptionWasSet();
+ break;
+
+ default:
+ error.SetErrorStringWithFormat("unrecognized short option '%c'", short_option);
+ break;
+ }
+
+ return error;
+ }
+
+ void
+ OptionParsingStarting() override
+ {
+ m_verbose.Clear();
+ }
+
+ const OptionDefinition*
+ GetDefinitions() override
+ {
+ return g_option_table;
+ }
+
+ OptionValueBoolean m_verbose;
+ static OptionDefinition g_option_table[];
+ };
+
CommandObjectObjC_ClassTable_Dump (CommandInterpreter &interpreter) :
CommandObjectParsed (interpreter,
"dump",
@@ -492,39 +542,116 @@ public:
"language objc class-table dump",
eCommandRequiresProcess |
eCommandProcessMustBeLaunched |
- eCommandProcessMustBePaused )
+ eCommandProcessMustBePaused ),
+ m_options(interpreter)
{
+ CommandArgumentEntry arg;
+ CommandArgumentData index_arg;
+
+ // Define the first (and only) variant of this arg.
+ index_arg.arg_type = eArgTypeRegularExpression;
+ index_arg.arg_repetition = eArgRepeatOptional;
+
+ // There is only one variant this argument could be; put it into the argument entry.
+ arg.push_back (index_arg);
+
+ // Push the data for the first argument into the m_arguments vector.
+ m_arguments.push_back (arg);
}
~CommandObjectObjC_ClassTable_Dump() override = default;
+ Options *
+ GetOptions() override
+ {
+ return &m_options;
+ }
+
protected:
bool
DoExecute(Args& command, CommandReturnObject &result) override
{
+ std::unique_ptr<RegularExpression> regex_up;
+ switch(command.GetArgumentCount())
+ {
+ case 0:
+ break;
+ case 1:
+ {
+ regex_up.reset(new RegularExpression());
+ if (!regex_up->Compile(command.GetArgumentAtIndex(0)))
+ {
+ result.AppendError("invalid argument - please provide a valid regular expression");
+ result.SetStatus(lldb::eReturnStatusFailed);
+ return false;
+ }
+ break;
+ }
+ default:
+ {
+ result.AppendError("please provide 0 or 1 arguments");
+ result.SetStatus(lldb::eReturnStatusFailed);
+ return false;
+ }
+ }
+
Process *process = m_exe_ctx.GetProcessPtr();
ObjCLanguageRuntime *objc_runtime = process->GetObjCLanguageRuntime();
if (objc_runtime)
{
auto iterators_pair = objc_runtime->GetDescriptorIteratorPair();
auto iterator = iterators_pair.first;
+ auto &std_out = result.GetOutputStream();
for(; iterator != iterators_pair.second; iterator++)
{
- result.GetOutputStream().Printf("isa = 0x%" PRIx64, iterator->first);
if (iterator->second)
{
- result.GetOutputStream().Printf(" name = %s", iterator->second->GetClassName().AsCString("<unknown>"));
- result.GetOutputStream().Printf(" instance size = %" PRIu64, iterator->second->GetInstanceSize());
- result.GetOutputStream().Printf(" num ivars = %" PRIuPTR, (uintptr_t)iterator->second->GetNumIVars());
+ const char* class_name = iterator->second->GetClassName().AsCString("<unknown>");
+ if (regex_up && class_name && !regex_up->Execute(class_name))
+ continue;
+ std_out.Printf("isa = 0x%" PRIx64, iterator->first);
+ std_out.Printf(" name = %s", class_name);
+ std_out.Printf(" instance size = %" PRIu64, iterator->second->GetInstanceSize());
+ std_out.Printf(" num ivars = %" PRIuPTR, (uintptr_t)iterator->second->GetNumIVars());
if (auto superclass = iterator->second->GetSuperclass())
{
- result.GetOutputStream().Printf(" superclass = %s", superclass->GetClassName().AsCString("<unknown>"));
+ std_out.Printf(" superclass = %s", superclass->GetClassName().AsCString("<unknown>"));
+ }
+ std_out.Printf("\n");
+ if (m_options.m_verbose)
+ {
+ for(size_t i = 0;
+ i < iterator->second->GetNumIVars();
+ i++)
+ {
+ auto ivar = iterator->second->GetIVarAtIndex(i);
+ std_out.Printf(" ivar name = %s type = %s size = %" PRIu64 " offset = %" PRId32 "\n",
+ ivar.m_name.AsCString("<unknown>"),
+ ivar.m_type.GetDisplayTypeName().AsCString("<unknown>"),
+ ivar.m_size,
+ ivar.m_offset);
+ }
+ iterator->second->Describe(nullptr,
+ [objc_runtime, &std_out] (const char* name, const char* type) -> bool {
+ std_out.Printf(" instance method name = %s type = %s\n",
+ name,
+ type);
+ return false;
+ },
+ [objc_runtime, &std_out] (const char* name, const char* type) -> bool {
+ std_out.Printf(" class method name = %s type = %s\n",
+ name,
+ type);
+ return false;
+ },
+ nullptr);
}
- result.GetOutputStream().Printf("\n");
}
else
{
- result.GetOutputStream().Printf(" has no associated class.\n");
+ if (regex_up && !regex_up->Execute(""))
+ continue;
+ std_out.Printf("isa = 0x%" PRIx64 " has no associated class.\n", iterator->first);
}
}
result.SetStatus(lldb::eReturnStatusSuccessFinishResult);
@@ -537,6 +664,15 @@ protected:
return false;
}
}
+
+ CommandOptions m_options;
+};
+
+OptionDefinition
+CommandObjectObjC_ClassTable_Dump::CommandOptions::g_option_table[] =
+{
+ { LLDB_OPT_SET_ALL, false, "verbose" , 'v', OptionParser::eNoArgument , nullptr, nullptr, 0, eArgTypeNone, "Print ivar and method information in detail"},
+ { 0 , false, nullptr , 0, 0 , nullptr, nullptr, 0, eArgTypeNone, nullptr }
};
class CommandObjectMultiwordObjC_TaggedPointer_Info : public CommandObjectParsed
@@ -639,11 +775,9 @@ protected:
class CommandObjectMultiwordObjC_ClassTable : public CommandObjectMultiword
{
public:
- CommandObjectMultiwordObjC_ClassTable (CommandInterpreter &interpreter) :
- CommandObjectMultiword (interpreter,
- "class-table",
- "A set of commands for operating on the Objective-C class table.",
- "class-table <subcommand> [<subcommand-options>]")
+ CommandObjectMultiwordObjC_ClassTable(CommandInterpreter &interpreter)
+ : CommandObjectMultiword(interpreter, "class-table", "Commands for operating on the Objective-C class table.",
+ "class-table <subcommand> [<subcommand-options>]")
{
LoadSubCommand ("dump", CommandObjectSP (new CommandObjectObjC_ClassTable_Dump (interpreter)));
}
@@ -654,12 +788,10 @@ public:
class CommandObjectMultiwordObjC_TaggedPointer : public CommandObjectMultiword
{
public:
-
- CommandObjectMultiwordObjC_TaggedPointer (CommandInterpreter &interpreter) :
- CommandObjectMultiword (interpreter,
- "tagged-pointer",
- "A set of commands for operating on Objective-C tagged pointers.",
- "class-table <subcommand> [<subcommand-options>]")
+ CommandObjectMultiwordObjC_TaggedPointer(CommandInterpreter &interpreter)
+ : CommandObjectMultiword(interpreter, "tagged-pointer",
+ "Commands for operating on Objective-C tagged pointers.",
+ "class-table <subcommand> [<subcommand-options>]")
{
LoadSubCommand ("info", CommandObjectSP (new CommandObjectMultiwordObjC_TaggedPointer_Info (interpreter)));
}
@@ -670,11 +802,9 @@ public:
class CommandObjectMultiwordObjC : public CommandObjectMultiword
{
public:
- CommandObjectMultiwordObjC (CommandInterpreter &interpreter) :
- CommandObjectMultiword (interpreter,
- "objc",
- "A set of commands for operating on the Objective-C Language Runtime.",
- "objc <subcommand> [<subcommand-options>]")
+ CommandObjectMultiwordObjC(CommandInterpreter &interpreter)
+ : CommandObjectMultiword(interpreter, "objc", "Commands for operating on the Objective-C language runtime.",
+ "objc <subcommand> [<subcommand-options>]")
{
LoadSubCommand ("class-table", CommandObjectSP (new CommandObjectMultiwordObjC_ClassTable (interpreter)));
LoadSubCommand ("tagged-pointer", CommandObjectSP (new CommandObjectMultiwordObjC_TaggedPointer (interpreter)));
@@ -733,6 +863,7 @@ AppleObjCRuntimeV2::CreateExceptionResolver (Breakpoint *bkpt, bool catch_bp, bo
eFunctionNameTypeBase,
eLanguageTypeUnknown,
Breakpoint::Exact,
+ 0,
eLazyBoolNo));
// FIXME: We don't do catch breakpoints for ObjC yet.
// Should there be some way for the runtime to specify what it can do in this regard?
@@ -1231,7 +1362,7 @@ AppleObjCRuntimeV2::UpdateISAToDescriptorMapDynamic(RemoteNXMapTable &hash_table
ExecutionContext exe_ctx;
- ThreadSP thread_sp = process->GetThreadList().GetSelectedThread();
+ ThreadSP thread_sp = process->GetThreadList().GetExpressionExecutionThread();
if (!thread_sp)
return false;
@@ -1241,13 +1372,13 @@ AppleObjCRuntimeV2::UpdateISAToDescriptorMapDynamic(RemoteNXMapTable &hash_table
if (!ast)
return false;
-
+
Address function_address;
-
- StreamString errors;
-
+
+ DiagnosticManager diagnostics;
+
const uint32_t addr_size = process->GetAddressByteSize();
-
+
Error err;
// Read the total number of classes from the hash table
@@ -1281,12 +1412,15 @@ AppleObjCRuntimeV2::UpdateISAToDescriptorMapDynamic(RemoteNXMapTable &hash_table
}
else
{
- errors.Clear();
-
- if (!m_get_class_info_code->Install(errors, exe_ctx))
+ diagnostics.Clear();
+
+ if (!m_get_class_info_code->Install(diagnostics, exe_ctx))
{
if (log)
- log->Printf ("Failed to install implementation lookup: %s.", errors.GetData());
+ {
+ log->Printf("Failed to install implementation lookup");
+ diagnostics.Dump(log);
+ }
m_get_class_info_code.reset();
}
}
@@ -1303,9 +1437,11 @@ AppleObjCRuntimeV2::UpdateISAToDescriptorMapDynamic(RemoteNXMapTable &hash_table
value.SetValueType (Value::eValueTypeScalar);
value.SetCompilerType (clang_uint32_t_type);
arguments.PushValue (value);
+ arguments.PushValue (value);
get_class_info_function = m_get_class_info_code->MakeFunctionCaller(clang_uint32_t_type,
arguments,
+ thread_sp,
error);
if (error.Fail())
@@ -1321,14 +1457,18 @@ AppleObjCRuntimeV2::UpdateISAToDescriptorMapDynamic(RemoteNXMapTable &hash_table
if (!get_class_info_function)
{
if (log)
- log->Printf ("Failed to get implementation lookup function caller: %s.", errors.GetData());
+ {
+ log->Printf("Failed to get implementation lookup function caller.");
+ diagnostics.Dump(log);
+ }
+
return false;
}
arguments = get_class_info_function->GetArgumentValues();
}
- errors.Clear();
-
+ diagnostics.Clear();
+
const uint32_t class_info_byte_size = addr_size + 4;
const uint32_t class_infos_byte_size = num_classes * class_info_byte_size;
lldb::addr_t class_infos_addr = process->AllocateMemory(class_infos_byte_size,
@@ -1337,23 +1477,22 @@ AppleObjCRuntimeV2::UpdateISAToDescriptorMapDynamic(RemoteNXMapTable &hash_table
if (class_infos_addr == LLDB_INVALID_ADDRESS)
return false;
-
- Mutex::Locker locker(m_get_class_info_args_mutex);
-
+
+ std::lock_guard<std::mutex> guard(m_get_class_info_args_mutex);
+
// Fill in our function argument values
arguments.GetValueAtIndex(0)->GetScalar() = hash_table.GetTableLoadAddress();
arguments.GetValueAtIndex(1)->GetScalar() = class_infos_addr;
arguments.GetValueAtIndex(2)->GetScalar() = class_infos_byte_size;
+ arguments.GetValueAtIndex(3)->GetScalar() = (GetLogIfAllCategoriesSet(LIBLLDB_LOG_TYPES) == nullptr ? 0 : 1);
+
bool success = false;
-
- errors.Clear();
-
+
+ diagnostics.Clear();
+
// Write our function arguments into the process so we can run our function
- if (get_class_info_function->WriteFunctionArguments (exe_ctx,
- m_get_class_info_args,
- arguments,
- errors))
+ if (get_class_info_function->WriteFunctionArguments(exe_ctx, m_get_class_info_args, arguments, diagnostics))
{
EvaluateExpressionOptions options;
options.SetUnwindOnError(true);
@@ -1365,18 +1504,15 @@ AppleObjCRuntimeV2::UpdateISAToDescriptorMapDynamic(RemoteNXMapTable &hash_table
Value return_value;
return_value.SetValueType (Value::eValueTypeScalar);
//return_value.SetContext (Value::eContextTypeClangType, clang_uint32_t_type);
- return_value.SetCompilerType (clang_uint32_t_type);
+ return_value.SetCompilerType(clang_uint32_t_type);
return_value.GetScalar() = 0;
-
- errors.Clear();
-
+
+ diagnostics.Clear();
+
// Run the function
- ExpressionResults results = get_class_info_function->ExecuteFunction (exe_ctx,
- &m_get_class_info_args,
- options,
- errors,
- return_value);
-
+ ExpressionResults results = get_class_info_function->ExecuteFunction(exe_ctx, &m_get_class_info_args, options,
+ diagnostics, return_value);
+
if (results == eExpressionCompleted)
{
// The result is the number of ClassInfo structures that were filled in
@@ -1401,15 +1537,21 @@ AppleObjCRuntimeV2::UpdateISAToDescriptorMapDynamic(RemoteNXMapTable &hash_table
else
{
if (log)
- log->Printf("Error evaluating our find class name function: %s.\n", errors.GetData());
+ {
+ log->Printf("Error evaluating our find class name function.");
+ diagnostics.Dump(log);
+ }
}
}
else
{
if (log)
- log->Printf ("Error writing function arguments: \"%s\".", errors.GetData());
+ {
+ log->Printf("Error writing function arguments.");
+ diagnostics.Dump(log);
+ }
}
-
+
// Deallocate the memory we allocated for the ClassInfo array
process->DeallocateMemory(class_infos_addr);
@@ -1475,7 +1617,7 @@ AppleObjCRuntimeV2::UpdateISAToDescriptorMapSharedCache()
ExecutionContext exe_ctx;
- ThreadSP thread_sp = process->GetThreadList().GetSelectedThread();
+ ThreadSP thread_sp = process->GetThreadList().GetExpressionExecutionThread();
if (!thread_sp)
return DescriptorMapUpdateResult::Fail();
@@ -1485,13 +1627,13 @@ AppleObjCRuntimeV2::UpdateISAToDescriptorMapSharedCache()
if (!ast)
return DescriptorMapUpdateResult::Fail();
-
+
Address function_address;
-
- StreamString errors;
-
+
+ DiagnosticManager diagnostics;
+
const uint32_t addr_size = process->GetAddressByteSize();
-
+
Error err;
const lldb::addr_t objc_opt_ptr = GetSharedCacheReadOnlyAddress();
@@ -1530,16 +1672,19 @@ AppleObjCRuntimeV2::UpdateISAToDescriptorMapSharedCache()
}
else
{
- errors.Clear();
-
- if (!m_get_shared_cache_class_info_code->Install(errors, exe_ctx))
+ diagnostics.Clear();
+
+ if (!m_get_shared_cache_class_info_code->Install(diagnostics, exe_ctx))
{
if (log)
- log->Printf ("Failed to install implementation lookup: %s.", errors.GetData());
+ {
+ log->Printf("Failed to install implementation lookup.");
+ diagnostics.Dump(log);
+ }
m_get_shared_cache_class_info_code.reset();
}
}
-
+
if (!m_get_shared_cache_class_info_code.get())
return DescriptorMapUpdateResult::Fail();
@@ -1555,9 +1700,11 @@ AppleObjCRuntimeV2::UpdateISAToDescriptorMapSharedCache()
//value.SetContext (Value::eContextTypeClangType, clang_uint32_t_type);
value.SetCompilerType (clang_uint32_t_type);
arguments.PushValue (value);
+ arguments.PushValue (value);
get_shared_cache_class_info_function = m_get_shared_cache_class_info_code->MakeFunctionCaller(clang_uint32_t_type,
arguments,
+ thread_sp,
error);
if (get_shared_cache_class_info_function == nullptr)
@@ -1571,9 +1718,9 @@ AppleObjCRuntimeV2::UpdateISAToDescriptorMapSharedCache()
return DescriptorMapUpdateResult::Fail();
arguments = get_shared_cache_class_info_function->GetArgumentValues();
}
-
- errors.Clear();
-
+
+ diagnostics.Clear();
+
const uint32_t class_info_byte_size = addr_size + 4;
const uint32_t class_infos_byte_size = num_classes * class_info_byte_size;
lldb::addr_t class_infos_addr = process->AllocateMemory (class_infos_byte_size,
@@ -1582,24 +1729,24 @@ AppleObjCRuntimeV2::UpdateISAToDescriptorMapSharedCache()
if (class_infos_addr == LLDB_INVALID_ADDRESS)
return DescriptorMapUpdateResult::Fail();
-
- Mutex::Locker locker(m_get_shared_cache_class_info_args_mutex);
-
+
+ std::lock_guard<std::mutex> guard(m_get_shared_cache_class_info_args_mutex);
+
// Fill in our function argument values
arguments.GetValueAtIndex(0)->GetScalar() = objc_opt_ptr;
arguments.GetValueAtIndex(1)->GetScalar() = class_infos_addr;
arguments.GetValueAtIndex(2)->GetScalar() = class_infos_byte_size;
+ arguments.GetValueAtIndex(3)->GetScalar() = (GetLogIfAllCategoriesSet(LIBLLDB_LOG_TYPES) == nullptr ? 0 : 1);
+
bool success = false;
bool any_found = false;
-
- errors.Clear();
-
+
+ diagnostics.Clear();
+
// Write our function arguments into the process so we can run our function
- if (get_shared_cache_class_info_function->WriteFunctionArguments (exe_ctx,
- m_get_shared_cache_class_info_args,
- arguments,
- errors))
+ if (get_shared_cache_class_info_function->WriteFunctionArguments(exe_ctx, m_get_shared_cache_class_info_args,
+ arguments, diagnostics))
{
EvaluateExpressionOptions options;
options.SetUnwindOnError(true);
@@ -1611,18 +1758,15 @@ AppleObjCRuntimeV2::UpdateISAToDescriptorMapSharedCache()
Value return_value;
return_value.SetValueType (Value::eValueTypeScalar);
//return_value.SetContext (Value::eContextTypeClangType, clang_uint32_t_type);
- return_value.SetCompilerType (clang_uint32_t_type);
+ return_value.SetCompilerType(clang_uint32_t_type);
return_value.GetScalar() = 0;
-
- errors.Clear();
-
+
+ diagnostics.Clear();
+
// Run the function
- ExpressionResults results = get_shared_cache_class_info_function->ExecuteFunction (exe_ctx,
- &m_get_shared_cache_class_info_args,
- options,
- errors,
- return_value);
-
+ ExpressionResults results = get_shared_cache_class_info_function->ExecuteFunction(
+ exe_ctx, &m_get_shared_cache_class_info_args, options, diagnostics, return_value);
+
if (results == eExpressionCompleted)
{
// The result is the number of ClassInfo structures that were filled in
@@ -1668,15 +1812,21 @@ AppleObjCRuntimeV2::UpdateISAToDescriptorMapSharedCache()
else
{
if (log)
- log->Printf("Error evaluating our find class name function: %s.\n", errors.GetData());
+ {
+ log->Printf("Error evaluating our find class name function.");
+ diagnostics.Dump(log);
+ }
}
}
else
{
if (log)
- log->Printf ("Error writing function arguments: \"%s\".", errors.GetData());
+ {
+ log->Printf("Error writing function arguments.");
+ diagnostics.Dump(log);
+ }
}
-
+
// Deallocate the memory we allocated for the ClassInfo array
process->DeallocateMemory(class_infos_addr);
@@ -1803,17 +1953,14 @@ AppleObjCRuntimeV2::WarnIfNoClassesCached ()
if (m_noclasses_warning_emitted)
return;
-#if defined(__APPLE__)
if (m_process &&
m_process->GetTarget().GetPlatform() &&
- m_process->GetTarget().GetPlatform()->GetPluginName() == PlatformiOSSimulator::GetPluginNameStatic())
+ m_process->GetTarget().GetPlatform()->GetPluginName().GetStringRef().endswith("-simulator"))
{
- // the iOS simulator does not have the objc_opt_ro class table
- // so don't actually complain to the user
+ // Simulators do not have the objc_opt_ro class table so don't actually complain to the user
m_noclasses_warning_emitted = true;
return;
}
-#endif
Debugger &debugger(GetProcess()->GetTarget().GetDebugger());
@@ -2025,6 +2172,74 @@ AppleObjCRuntimeV2::TaggedPointerVendorV2::CreateInstance (AppleObjCRuntimeV2& r
if (error.Fail())
return new TaggedPointerVendorLegacy(runtime);
+ // try to detect the "extended tagged pointer" variables - if any are missing, use the non-extended vendor
+ do
+ {
+ auto objc_debug_taggedpointer_ext_mask = ExtractRuntimeGlobalSymbol(process,
+ ConstString("objc_debug_taggedpointer_ext_mask"),
+ objc_module_sp,
+ error);
+ if (error.Fail())
+ break;
+
+ auto objc_debug_taggedpointer_ext_slot_shift = ExtractRuntimeGlobalSymbol(process,
+ ConstString("objc_debug_taggedpointer_ext_slot_shift"),
+ objc_module_sp,
+ error,
+ true,
+ 4);
+ if (error.Fail())
+ break;
+
+ auto objc_debug_taggedpointer_ext_slot_mask = ExtractRuntimeGlobalSymbol(process,
+ ConstString("objc_debug_taggedpointer_ext_slot_mask"),
+ objc_module_sp,
+ error,
+ true,
+ 4);
+ if (error.Fail())
+ break;
+
+ auto objc_debug_taggedpointer_ext_classes = ExtractRuntimeGlobalSymbol(process,
+ ConstString("objc_debug_taggedpointer_ext_classes"),
+ objc_module_sp,
+ error,
+ false);
+ if (error.Fail())
+ break;
+
+ auto objc_debug_taggedpointer_ext_payload_lshift = ExtractRuntimeGlobalSymbol(process,
+ ConstString("objc_debug_taggedpointer_ext_payload_lshift"),
+ objc_module_sp,
+ error,
+ true,
+ 4);
+ if (error.Fail())
+ break;
+
+ auto objc_debug_taggedpointer_ext_payload_rshift = ExtractRuntimeGlobalSymbol(process,
+ ConstString("objc_debug_taggedpointer_ext_payload_rshift"),
+ objc_module_sp,
+ error,
+ true,
+ 4);
+ if (error.Fail())
+ break;
+
+ return new TaggedPointerVendorExtended(runtime,
+ objc_debug_taggedpointer_mask,
+ objc_debug_taggedpointer_ext_mask,
+ objc_debug_taggedpointer_slot_shift,
+ objc_debug_taggedpointer_ext_slot_shift,
+ objc_debug_taggedpointer_slot_mask,
+ objc_debug_taggedpointer_ext_slot_mask,
+ objc_debug_taggedpointer_payload_lshift,
+ objc_debug_taggedpointer_payload_rshift,
+ objc_debug_taggedpointer_ext_payload_lshift,
+ objc_debug_taggedpointer_ext_payload_rshift,
+ objc_debug_taggedpointer_classes,
+ objc_debug_taggedpointer_ext_classes);
+ } while(false);
// we might want to have some rules to outlaw these values (e.g if the table's address is zero)
@@ -2164,6 +2379,87 @@ AppleObjCRuntimeV2::TaggedPointerVendorRuntimeAssisted::GetClassDescriptor (lldb
return ClassDescriptorSP(new ClassDescriptorV2Tagged(actual_class_descriptor_sp,data_payload));
}
+AppleObjCRuntimeV2::TaggedPointerVendorExtended::TaggedPointerVendorExtended (AppleObjCRuntimeV2& runtime,
+ uint64_t objc_debug_taggedpointer_mask,
+ uint64_t objc_debug_taggedpointer_ext_mask,
+ uint32_t objc_debug_taggedpointer_slot_shift,
+ uint32_t objc_debug_taggedpointer_ext_slot_shift,
+ uint32_t objc_debug_taggedpointer_slot_mask,
+ uint32_t objc_debug_taggedpointer_ext_slot_mask,
+ uint32_t objc_debug_taggedpointer_payload_lshift,
+ uint32_t objc_debug_taggedpointer_payload_rshift,
+ uint32_t objc_debug_taggedpointer_ext_payload_lshift,
+ uint32_t objc_debug_taggedpointer_ext_payload_rshift,
+ lldb::addr_t objc_debug_taggedpointer_classes,
+ lldb::addr_t objc_debug_taggedpointer_ext_classes) :
+TaggedPointerVendorRuntimeAssisted(runtime,
+ objc_debug_taggedpointer_mask,
+ objc_debug_taggedpointer_slot_shift,
+ objc_debug_taggedpointer_slot_mask,
+ objc_debug_taggedpointer_payload_lshift,
+ objc_debug_taggedpointer_payload_rshift,
+ objc_debug_taggedpointer_classes),
+m_ext_cache(),
+m_objc_debug_taggedpointer_ext_mask(objc_debug_taggedpointer_ext_mask),
+m_objc_debug_taggedpointer_ext_slot_shift(objc_debug_taggedpointer_ext_slot_shift),
+m_objc_debug_taggedpointer_ext_slot_mask(objc_debug_taggedpointer_ext_slot_mask),
+m_objc_debug_taggedpointer_ext_payload_lshift(objc_debug_taggedpointer_ext_payload_lshift),
+m_objc_debug_taggedpointer_ext_payload_rshift(objc_debug_taggedpointer_ext_payload_rshift),
+m_objc_debug_taggedpointer_ext_classes(objc_debug_taggedpointer_ext_classes)
+{
+}
+
+bool
+AppleObjCRuntimeV2::TaggedPointerVendorExtended::IsPossibleExtendedTaggedPointer (lldb::addr_t ptr)
+{
+ if (!IsPossibleTaggedPointer(ptr))
+ return false;
+
+ if (m_objc_debug_taggedpointer_ext_mask == 0)
+ return false;
+
+ return ((ptr & m_objc_debug_taggedpointer_ext_mask) == m_objc_debug_taggedpointer_ext_mask);
+}
+
+ObjCLanguageRuntime::ClassDescriptorSP
+AppleObjCRuntimeV2::TaggedPointerVendorExtended::GetClassDescriptor (lldb::addr_t ptr)
+{
+ ClassDescriptorSP actual_class_descriptor_sp;
+ uint64_t data_payload;
+
+ if (!IsPossibleTaggedPointer(ptr))
+ return ObjCLanguageRuntime::ClassDescriptorSP();
+
+ if (!IsPossibleExtendedTaggedPointer(ptr))
+ return this->TaggedPointerVendorRuntimeAssisted::GetClassDescriptor(ptr);
+
+ uintptr_t slot = (ptr >> m_objc_debug_taggedpointer_ext_slot_shift) & m_objc_debug_taggedpointer_ext_slot_mask;
+
+ CacheIterator iterator = m_ext_cache.find(slot),
+ end = m_ext_cache.end();
+ if (iterator != end)
+ {
+ actual_class_descriptor_sp = iterator->second;
+ }
+ else
+ {
+ Process* process(m_runtime.GetProcess());
+ uintptr_t slot_ptr = slot*process->GetAddressByteSize()+m_objc_debug_taggedpointer_ext_classes;
+ Error error;
+ uintptr_t slot_data = process->ReadPointerFromMemory(slot_ptr, error);
+ if (error.Fail() || slot_data == 0 || slot_data == uintptr_t(LLDB_INVALID_ADDRESS))
+ return nullptr;
+ actual_class_descriptor_sp = m_runtime.GetClassDescriptorFromISA((ObjCISA)slot_data);
+ if (!actual_class_descriptor_sp)
+ return ObjCLanguageRuntime::ClassDescriptorSP();
+ m_ext_cache[slot] = actual_class_descriptor_sp;
+ }
+
+ data_payload = (((uint64_t)ptr << m_objc_debug_taggedpointer_ext_payload_lshift) >> m_objc_debug_taggedpointer_ext_payload_rshift);
+
+ return ClassDescriptorSP(new ClassDescriptorV2Tagged(actual_class_descriptor_sp,data_payload));
+}
+
AppleObjCRuntimeV2::NonPointerISACache::NonPointerISACache (AppleObjCRuntimeV2& runtime,
uint64_t objc_debug_isa_class_mask,
uint64_t objc_debug_isa_magic_mask,
diff --git a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h
index 96b47e8770f9..4b27c7400481 100644
--- a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h
+++ b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h
@@ -14,6 +14,7 @@
// C++ Includes
#include <map>
#include <memory>
+#include <mutex>
// Other libraries and framework includes
// Project includes
@@ -234,6 +235,45 @@ private:
DISALLOW_COPY_AND_ASSIGN(TaggedPointerVendorRuntimeAssisted);
};
+ class TaggedPointerVendorExtended : public TaggedPointerVendorRuntimeAssisted
+ {
+ public:
+ ObjCLanguageRuntime::ClassDescriptorSP
+ GetClassDescriptor(lldb::addr_t ptr) override;
+
+ protected:
+ TaggedPointerVendorExtended (AppleObjCRuntimeV2& runtime,
+ uint64_t objc_debug_taggedpointer_mask,
+ uint64_t objc_debug_taggedpointer_ext_mask,
+ uint32_t objc_debug_taggedpointer_slot_shift,
+ uint32_t objc_debug_taggedpointer_ext_slot_shift,
+ uint32_t objc_debug_taggedpointer_slot_mask,
+ uint32_t objc_debug_taggedpointer_ext_slot_mask,
+ uint32_t objc_debug_taggedpointer_payload_lshift,
+ uint32_t objc_debug_taggedpointer_payload_rshift,
+ uint32_t objc_debug_taggedpointer_ext_payload_lshift,
+ uint32_t objc_debug_taggedpointer_ext_payload_rshift,
+ lldb::addr_t objc_debug_taggedpointer_classes,
+ lldb::addr_t objc_debug_taggedpointer_ext_classes);
+
+ bool
+ IsPossibleExtendedTaggedPointer (lldb::addr_t ptr);
+
+ typedef std::map<uint8_t,ObjCLanguageRuntime::ClassDescriptorSP> Cache;
+ typedef Cache::iterator CacheIterator;
+ Cache m_ext_cache;
+ uint64_t m_objc_debug_taggedpointer_ext_mask;
+ uint32_t m_objc_debug_taggedpointer_ext_slot_shift;
+ uint32_t m_objc_debug_taggedpointer_ext_slot_mask;
+ uint32_t m_objc_debug_taggedpointer_ext_payload_lshift;
+ uint32_t m_objc_debug_taggedpointer_ext_payload_rshift;
+ lldb::addr_t m_objc_debug_taggedpointer_ext_classes;
+
+ friend class AppleObjCRuntimeV2::TaggedPointerVendorV2;
+
+ DISALLOW_COPY_AND_ASSIGN(TaggedPointerVendorExtended);
+ };
+
class TaggedPointerVendorLegacy : public TaggedPointerVendorV2
{
public:
@@ -314,11 +354,11 @@ private:
std::unique_ptr<UtilityFunction> m_get_class_info_code;
lldb::addr_t m_get_class_info_args;
- Mutex m_get_class_info_args_mutex;
+ std::mutex m_get_class_info_args_mutex;
std::unique_ptr<UtilityFunction> m_get_shared_cache_class_info_code;
lldb::addr_t m_get_shared_cache_class_info_args;
- Mutex m_get_shared_cache_class_info_args_mutex;
+ std::mutex m_get_shared_cache_class_info_args_mutex;
std::unique_ptr<DeclVendor> m_decl_vendor_ap;
lldb::addr_t m_isa_hash_table_ptr;
diff --git a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.cpp b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.cpp
index d38a076ad5d7..5fedb80e29a6 100644
--- a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.cpp
+++ b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.cpp
@@ -22,19 +22,20 @@
#include "lldb/Core/Module.h"
#include "lldb/Core/StreamFile.h"
#include "lldb/Core/Value.h"
-#include "lldb/Expression/UserExpression.h"
+#include "lldb/Expression/DiagnosticManager.h"
#include "lldb/Expression/FunctionCaller.h"
+#include "lldb/Expression/UserExpression.h"
#include "lldb/Expression/UtilityFunction.h"
#include "lldb/Host/FileSpec.h"
#include "lldb/Symbol/ClangASTContext.h"
#include "lldb/Symbol/Symbol.h"
#include "lldb/Target/ABI.h"
+#include "lldb/Target/ExecutionContext.h"
#include "lldb/Target/ObjCLanguageRuntime.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/RegisterContext.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/Thread.h"
-#include "lldb/Target/ExecutionContext.h"
#include "lldb/Target/ThreadPlanRunToAddress.h"
#include "llvm/ADT/STLExtras.h"
@@ -43,7 +44,6 @@ using namespace lldb;
using namespace lldb_private;
const char *AppleObjCTrampolineHandler::g_lookup_implementation_function_name = "__lldb_objc_find_implementation_for_selector";
-const char *AppleObjCTrampolineHandler::g_lookup_implementation_function_code = NULL;
const char *AppleObjCTrampolineHandler::g_lookup_implementation_with_stret_function_code = " \n\
extern \"C\" \n\
{ \n\
@@ -461,7 +461,7 @@ AppleObjCTrampolineHandler::AppleObjCVTables::InitializeVTableSymbols ()
Target &target = process_sp->GetTarget();
const ModuleList &target_modules = target.GetImages();
- Mutex::Locker modules_locker(target_modules.GetMutex());
+ std::lock_guard<std::recursive_mutex> guard(target_modules.GetMutex());
size_t num_modules = target_modules.GetSize();
if (!m_objc_module_sp)
{
@@ -657,6 +657,7 @@ AppleObjCTrampolineHandler::AppleObjCTrampolineHandler (const ProcessSP &process
const ModuleSP &objc_module_sp) :
m_process_wp (),
m_objc_module_sp (objc_module_sp),
+ m_lookup_implementation_function_code(nullptr),
m_impl_fn_addr (LLDB_INVALID_ADDRESS),
m_impl_stret_fn_addr (LLDB_INVALID_ADDRESS),
m_msg_forward_addr (LLDB_INVALID_ADDRESS)
@@ -703,11 +704,11 @@ AppleObjCTrampolineHandler::AppleObjCTrampolineHandler (const ProcessSP &process
// It there is no stret return lookup function, assume that it is the same as the straight lookup:
m_impl_stret_fn_addr = m_impl_fn_addr;
// Also we will use the version of the lookup code that doesn't rely on the stret version of the function.
- g_lookup_implementation_function_code = g_lookup_implementation_no_stret_function_code;
+ m_lookup_implementation_function_code = g_lookup_implementation_no_stret_function_code;
}
else
{
- g_lookup_implementation_function_code = g_lookup_implementation_with_stret_function_code;
+ m_lookup_implementation_function_code = g_lookup_implementation_with_stret_function_code;
}
// Look up the addresses for the objc dispatch functions and cache them. For now I'm inspecting the symbol
@@ -738,26 +739,28 @@ AppleObjCTrampolineHandler::AppleObjCTrampolineHandler (const ProcessSP &process
}
lldb::addr_t
-AppleObjCTrampolineHandler::SetupDispatchFunction (Thread &thread, ValueList &dispatch_values)
+AppleObjCTrampolineHandler::SetupDispatchFunction(Thread &thread, ValueList &dispatch_values)
{
- ExecutionContext exe_ctx (thread.shared_from_this());
- StreamString errors;
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
+ ThreadSP thread_sp(thread.shared_from_this());
+ ExecutionContext exe_ctx (thread_sp);
+ DiagnosticManager diagnostics;
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP));
+
lldb::addr_t args_addr = LLDB_INVALID_ADDRESS;
FunctionCaller *impl_function_caller = nullptr;
// Scope for mutex locker:
{
- Mutex::Locker locker(m_impl_function_mutex);
-
+ std::lock_guard<std::mutex> guard(m_impl_function_mutex);
+
// First stage is to make the ClangUtility to hold our injected function:
if (!m_impl_code.get())
{
- if (g_lookup_implementation_function_code != NULL)
+ if (m_lookup_implementation_function_code != NULL)
{
Error error;
- m_impl_code.reset (exe_ctx.GetTargetRef().GetUtilityFunctionForLanguage (g_lookup_implementation_function_code,
+ m_impl_code.reset (exe_ctx.GetTargetRef().GetUtilityFunctionForLanguage (m_lookup_implementation_function_code,
eLanguageTypeObjC,
g_lookup_implementation_function_name,
error));
@@ -768,11 +771,14 @@ AppleObjCTrampolineHandler::SetupDispatchFunction (Thread &thread, ValueList &di
m_impl_code.reset();
return args_addr;
}
-
- if (!m_impl_code->Install(errors, exe_ctx))
+
+ if (!m_impl_code->Install(diagnostics, exe_ctx))
{
if (log)
- log->Printf ("Failed to install implementation lookup: %s.", errors.GetData());
+ {
+ log->Printf("Failed to install implementation lookup.");
+ diagnostics.Dump(log);
+ }
m_impl_code.reset();
return args_addr;
}
@@ -781,10 +787,8 @@ AppleObjCTrampolineHandler::SetupDispatchFunction (Thread &thread, ValueList &di
{
if (log)
log->Printf("No method lookup implementation code.");
- errors.Printf ("No method lookup implementation code found.");
return LLDB_INVALID_ADDRESS;
}
-
// Next make the runner function for our implementation utility function.
ClangASTContext *clang_ast_context = thread.GetProcess()->GetTarget().GetScratchClangASTContext();
@@ -793,6 +797,7 @@ AppleObjCTrampolineHandler::SetupDispatchFunction (Thread &thread, ValueList &di
impl_function_caller = m_impl_code->MakeFunctionCaller(clang_void_ptr_type,
dispatch_values,
+ thread_sp,
error);
if (error.Fail())
{
@@ -806,20 +811,23 @@ AppleObjCTrampolineHandler::SetupDispatchFunction (Thread &thread, ValueList &di
impl_function_caller = m_impl_code->GetFunctionCaller();
}
}
-
- errors.Clear();
-
+
+ diagnostics.Clear();
+
// Now write down the argument values for this particular call. This looks like it might be a race condition
// if other threads were calling into here, but actually it isn't because we allocate a new args structure for
// this call by passing args_addr = LLDB_INVALID_ADDRESS...
- if (impl_function_caller->WriteFunctionArguments (exe_ctx, args_addr, dispatch_values, errors))
+ if (!impl_function_caller->WriteFunctionArguments(exe_ctx, args_addr, dispatch_values, diagnostics))
{
if (log)
- log->Printf ("Error writing function arguments: \"%s\".", errors.GetData());
+ {
+ log->Printf("Error writing function arguments.");
+ diagnostics.Dump(log);
+ }
return args_addr;
}
-
+
return args_addr;
}
diff --git a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.h b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.h
index 42d3461ddfa5..c0d1944a7f2f 100644
--- a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.h
+++ b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.h
@@ -13,12 +13,12 @@
// C Includes
// C++ Includes
#include <map>
+#include <mutex>
#include <vector>
// Other libraries and framework includes
// Project includes
#include "lldb/lldb-public.h"
-#include "lldb/Host/Mutex.h"
#include "lldb/Expression/UtilityFunction.h"
namespace lldb_private
@@ -65,7 +65,6 @@ public:
private:
static const char *g_lookup_implementation_function_name;
- static const char *g_lookup_implementation_function_code;
static const char *g_lookup_implementation_with_stret_function_code;
static const char *g_lookup_implementation_no_stret_function_code;
@@ -195,8 +194,9 @@ private:
MsgsendMap m_msgSend_map;
lldb::ProcessWP m_process_wp;
lldb::ModuleSP m_objc_module_sp;
+ const char *m_lookup_implementation_function_code;
std::unique_ptr<UtilityFunction> m_impl_code;
- Mutex m_impl_function_mutex;
+ std::mutex m_impl_function_mutex;
lldb::addr_t m_impl_fn_addr;
lldb::addr_t m_impl_stret_fn_addr;
lldb::addr_t m_msg_forward_addr;
diff --git a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.cpp b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.cpp
index 9308c7a668d2..d4adc094bc1b 100644
--- a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.cpp
+++ b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.cpp
@@ -10,6 +10,7 @@
#include "AppleObjCTypeEncodingParser.h"
#include "lldb/Symbol/ClangASTContext.h"
+#include "lldb/Symbol/ClangUtil.h"
#include "lldb/Symbol/CompilerType.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/Target.h"
@@ -155,7 +156,7 @@ AppleObjCTypeEncodingParser::BuildAggregate (clang::ASTContext &ast_ctx, lldb_ut
}
ClangASTContext::CompleteTagDeclarationDefinition(union_type);
}
- return ClangASTContext::GetQualType(union_type);
+ return ClangUtil::GetQualType(union_type);
}
clang::QualType
@@ -171,7 +172,7 @@ AppleObjCTypeEncodingParser::BuildArray (clang::ASTContext &ast_ctx, lldb_utilit
if (!lldb_ctx)
return clang::QualType();
CompilerType array_type(lldb_ctx->CreateArrayType(CompilerType(&ast_ctx, element_type), size, false));
- return ClangASTContext::GetQualType(array_type);
+ return ClangUtil::GetQualType(array_type);
}
// the runtime can emit these in the form of @"SomeType", giving more specifics
@@ -261,8 +262,8 @@ AppleObjCTypeEncodingParser::BuildObjCObjectPointerType (clang::ASTContext &ast_
if (!num_types)
return ast_ctx.getObjCIdType();
#endif
-
- return ClangASTContext::GetQualType(ClangASTContext::GetTypeForDecl(decls[0]).GetPointerType());
+
+ return ClangUtil::GetQualType(ClangASTContext::GetTypeForDecl(decls[0]).GetPointerType());
}
else
{
diff --git a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.cpp b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.cpp
index 285786a09dbb..a2101c927b4d 100644
--- a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.cpp
+++ b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.cpp
@@ -13,16 +13,16 @@
// Project includes
#include "AppleThreadPlanStepThroughObjCTrampoline.h"
#include "AppleObjCTrampolineHandler.h"
-#include "lldb/Target/Process.h"
-#include "lldb/Target/Thread.h"
+#include "lldb/Core/Log.h"
+#include "lldb/Expression/DiagnosticManager.h"
#include "lldb/Expression/FunctionCaller.h"
#include "lldb/Expression/UtilityFunction.h"
#include "lldb/Target/ExecutionContext.h"
#include "lldb/Target/ObjCLanguageRuntime.h"
+#include "lldb/Target/Process.h"
+#include "lldb/Target/Thread.h"
#include "lldb/Target/ThreadPlanRunToAddress.h"
#include "lldb/Target/ThreadPlanStepOut.h"
-#include "lldb/Core/Log.h"
-
using namespace lldb;
using namespace lldb_private;
@@ -75,9 +75,9 @@ AppleThreadPlanStepThroughObjCTrampoline::InitializeFunctionCaller ()
{
if (!m_func_sp)
{
- StreamString errors;
+ DiagnosticManager diagnostics;
m_args_addr = m_trampoline_handler->SetupDispatchFunction(m_thread, m_input_values);
-
+
if (m_args_addr == LLDB_INVALID_ADDRESS)
{
return false;
@@ -89,12 +89,9 @@ AppleThreadPlanStepThroughObjCTrampoline::InitializeFunctionCaller ()
options.SetIgnoreBreakpoints(true);
options.SetStopOthers(m_stop_others);
m_thread.CalculateExecutionContext(exc_ctx);
- m_func_sp = m_impl_function->GetThreadPlanToCallFunction (exc_ctx,
- m_args_addr,
- options,
- errors);
+ m_func_sp = m_impl_function->GetThreadPlanToCallFunction(exc_ctx, m_args_addr, options, diagnostics);
m_func_sp->SetOkayToDiscard(true);
- m_thread.QueueThreadPlan (m_func_sp, false);
+ m_thread.QueueThreadPlan(m_func_sp, false);
}
return true;
}
diff --git a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/Makefile b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/Makefile
deleted file mode 100644
index 485fe75b3f88..000000000000
--- a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/Makefile
+++ /dev/null
@@ -1,14 +0,0 @@
-##===- source/Plugins/LangRuntime/ObjC/AppleRT/Makefile ----*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LLDB_LEVEL := ../../../../..
-LIBRARYNAME := lldbPluginAppleObjCRuntime
-BUILD_ARCHIVE = 1
-
-include $(LLDB_LEVEL)/Makefile
diff --git a/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/Makefile b/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/Makefile
deleted file mode 100644
index eeb50ae3fcae..000000000000
--- a/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/Makefile
+++ /dev/null
@@ -1,14 +0,0 @@
-##===- Source/Plugins/LangRuntime/RenderScript/RenderScriptRuntime/Makefile ----*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LLDB_LEVEL := ../../../../..
-LIBRARYNAME := lldbPluginRenderScriptRuntime
-BUILD_ARCHIVE = 1
-
-include $(LLDB_LEVEL)/Makefile
diff --git a/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.cpp b/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.cpp
index 8e5d31b66350..7441fd991511 100644
--- a/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.cpp
+++ b/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.cpp
@@ -13,50 +13,49 @@
// Project includes
#include "RenderScriptRuntime.h"
+#include "lldb/Breakpoint/StoppointCallbackContext.h"
#include "lldb/Core/ConstString.h"
#include "lldb/Core/Debugger.h"
#include "lldb/Core/Error.h"
#include "lldb/Core/Log.h"
#include "lldb/Core/PluginManager.h"
-#include "lldb/Core/ValueObjectVariable.h"
#include "lldb/Core/RegularExpression.h"
+#include "lldb/Core/ValueObjectVariable.h"
#include "lldb/DataFormatters/DumpValueObjectOptions.h"
+#include "lldb/Expression/UserExpression.h"
#include "lldb/Host/StringConvert.h"
+#include "lldb/Interpreter/Args.h"
+#include "lldb/Interpreter/CommandInterpreter.h"
+#include "lldb/Interpreter/CommandObjectMultiword.h"
+#include "lldb/Interpreter/CommandReturnObject.h"
+#include "lldb/Interpreter/Options.h"
#include "lldb/Symbol/Symbol.h"
#include "lldb/Symbol/Type.h"
+#include "lldb/Symbol/VariableList.h"
#include "lldb/Target/Process.h"
+#include "lldb/Target/RegisterContext.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/Thread.h"
-#include "lldb/Interpreter/Args.h"
-#include "lldb/Interpreter/Options.h"
-#include "lldb/Interpreter/CommandInterpreter.h"
-#include "lldb/Interpreter/CommandReturnObject.h"
-#include "lldb/Interpreter/CommandObjectMultiword.h"
-#include "lldb/Breakpoint/StoppointCallbackContext.h"
-#include "lldb/Target/RegisterContext.h"
-#include "lldb/Expression/UserExpression.h"
-#include "lldb/Symbol/VariableList.h"
using namespace lldb;
using namespace lldb_private;
using namespace lldb_renderscript;
-namespace {
+namespace
+{
// The empirical_type adds a basic level of validation to arbitrary data
// allowing us to track if data has been discovered and stored or not.
// An empirical_type will be marked as valid only if it has been explicitly assigned to.
-template <typename type_t>
-class empirical_type
+template <typename type_t> class empirical_type
{
public:
// Ctor. Contents is invalid when constructed.
- empirical_type()
- : valid(false)
- {}
+ empirical_type() : valid(false) {}
// Return true and copy contents to out if valid, else return false.
- bool get(type_t& out) const
+ bool
+ get(type_t &out) const
{
if (valid)
out = data;
@@ -64,32 +63,37 @@ public:
}
// Return a pointer to the contents or nullptr if it was not valid.
- const type_t* get() const
+ const type_t *
+ get() const
{
return valid ? &data : nullptr;
}
// Assign data explicitly.
- void set(const type_t in)
+ void
+ set(const type_t in)
{
data = in;
valid = true;
}
// Mark contents as invalid.
- void invalidate()
+ void
+ invalidate()
{
valid = false;
}
// Returns true if this type contains valid data.
- bool isValid() const
+ bool
+ isValid() const
{
return valid;
}
// Assignment operator.
- empirical_type<type_t>& operator = (const type_t in)
+ empirical_type<type_t> &
+ operator=(const type_t in)
{
set(in);
return *this;
@@ -97,7 +101,7 @@ public:
// Dereference operator returns contents.
// Warning: Will assert if not valid so use only when you know data is valid.
- const type_t& operator * () const
+ const type_t &operator*() const
{
assert(valid);
return data;
@@ -108,6 +112,378 @@ protected:
type_t data;
};
+// ArgItem is used by the GetArgs() function when reading function arguments from the target.
+struct ArgItem
+{
+ enum
+ {
+ ePointer,
+ eInt32,
+ eInt64,
+ eLong,
+ eBool
+ } type;
+
+ uint64_t value;
+
+ explicit operator uint64_t() const { return value; }
+};
+
+// Context structure to be passed into GetArgsXXX(), argument reading functions below.
+struct GetArgsCtx
+{
+ RegisterContext *reg_ctx;
+ Process *process;
+};
+
+bool
+GetArgsX86(const GetArgsCtx &ctx, ArgItem *arg_list, size_t num_args)
+{
+ Log *log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE);
+
+ Error error;
+
+ // get the current stack pointer
+ uint64_t sp = ctx.reg_ctx->GetSP();
+
+ for (size_t i = 0; i < num_args; ++i)
+ {
+ ArgItem &arg = arg_list[i];
+ // advance up the stack by one argument
+ sp += sizeof(uint32_t);
+ // get the argument type size
+ size_t arg_size = sizeof(uint32_t);
+ // read the argument from memory
+ arg.value = 0;
+ Error error;
+ size_t read = ctx.process->ReadMemory(sp, &arg.value, sizeof(uint32_t), error);
+ if (read != arg_size || !error.Success())
+ {
+ if (log)
+ log->Printf("%s - error reading argument: %" PRIu64 " '%s'", __FUNCTION__, uint64_t(i),
+ error.AsCString());
+ return false;
+ }
+ }
+ return true;
+}
+
+bool
+GetArgsX86_64(GetArgsCtx &ctx, ArgItem *arg_list, size_t num_args)
+{
+ Log *log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE);
+
+ // number of arguments passed in registers
+ static const uint32_t c_args_in_reg = 6;
+ // register passing order
+ static const std::array<const char *, c_args_in_reg> c_reg_names{{"rdi", "rsi", "rdx", "rcx", "r8", "r9"}};
+ // argument type to size mapping
+ static const std::array<size_t, 5> arg_size{{
+ 8, // ePointer,
+ 4, // eInt32,
+ 8, // eInt64,
+ 8, // eLong,
+ 4, // eBool,
+ }};
+
+ Error error;
+
+ // get the current stack pointer
+ uint64_t sp = ctx.reg_ctx->GetSP();
+ // step over the return address
+ sp += sizeof(uint64_t);
+
+ // check the stack alignment was correct (16 byte aligned)
+ if ((sp & 0xf) != 0x0)
+ {
+ if (log)
+ log->Printf("%s - stack misaligned", __FUNCTION__);
+ return false;
+ }
+
+ // find the start of arguments on the stack
+ uint64_t sp_offset = 0;
+ for (uint32_t i = c_args_in_reg; i < num_args; ++i)
+ {
+ sp_offset += arg_size[arg_list[i].type];
+ }
+ // round up to multiple of 16
+ sp_offset = (sp_offset + 0xf) & 0xf;
+ sp += sp_offset;
+
+ for (size_t i = 0; i < num_args; ++i)
+ {
+ bool success = false;
+ ArgItem &arg = arg_list[i];
+ // arguments passed in registers
+ if (i < c_args_in_reg)
+ {
+ const RegisterInfo *rArg = ctx.reg_ctx->GetRegisterInfoByName(c_reg_names[i]);
+ RegisterValue rVal;
+ if (ctx.reg_ctx->ReadRegister(rArg, rVal))
+ arg.value = rVal.GetAsUInt64(0, &success);
+ }
+ // arguments passed on the stack
+ else
+ {
+ // get the argument type size
+ const size_t size = arg_size[arg_list[i].type];
+ // read the argument from memory
+ arg.value = 0;
+ // note: due to little endian layout reading 4 or 8 bytes will give the correct value.
+ size_t read = ctx.process->ReadMemory(sp, &arg.value, size, error);
+ success = (error.Success() && read==size);
+ // advance past this argument
+ sp -= size;
+ }
+ // fail if we couldn't read this argument
+ if (!success)
+ {
+ if (log)
+ log->Printf("%s - error reading argument: %" PRIu64", reason: %s",
+ __FUNCTION__, uint64_t(i), error.AsCString("n/a"));
+ return false;
+ }
+ }
+ return true;
+}
+
+bool
+GetArgsArm(GetArgsCtx &ctx, ArgItem *arg_list, size_t num_args)
+{
+ // number of arguments passed in registers
+ static const uint32_t c_args_in_reg = 4;
+
+ Log *log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE);
+
+ Error error;
+
+ // get the current stack pointer
+ uint64_t sp = ctx.reg_ctx->GetSP();
+
+ for (size_t i = 0; i < num_args; ++i)
+ {
+ bool success = false;
+ ArgItem &arg = arg_list[i];
+ // arguments passed in registers
+ if (i < c_args_in_reg)
+ {
+ const RegisterInfo *rArg = ctx.reg_ctx->GetRegisterInfoAtIndex(i);
+ RegisterValue rVal;
+ if (ctx.reg_ctx->ReadRegister(rArg, rVal))
+ arg.value = rVal.GetAsUInt32(0, &success);
+ }
+ // arguments passed on the stack
+ else
+ {
+ // get the argument type size
+ const size_t arg_size = sizeof(uint32_t);
+ // clear all 64bits
+ arg.value = 0;
+ // read this argument from memory
+ size_t bytes_read = ctx.process->ReadMemory(sp, &arg.value, arg_size, error);
+ success = (error.Success() && bytes_read == arg_size);
+ // advance the stack pointer
+ sp += sizeof(uint32_t);
+ }
+ // fail if we couldn't read this argument
+ if (!success)
+ {
+ if (log)
+ log->Printf("%s - error reading argument: %" PRIu64", reason: %s",
+ __FUNCTION__, uint64_t(i), error.AsCString("n/a"));
+ return false;
+ }
+ }
+ return true;
+}
+
+bool
+GetArgsAarch64(GetArgsCtx &ctx, ArgItem *arg_list, size_t num_args)
+{
+ // number of arguments passed in registers
+ static const uint32_t c_args_in_reg = 8;
+
+ Log *log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE);
+
+ for (size_t i = 0; i < num_args; ++i)
+ {
+ bool success = false;
+ ArgItem &arg = arg_list[i];
+ // arguments passed in registers
+ if (i < c_args_in_reg)
+ {
+ const RegisterInfo *rArg = ctx.reg_ctx->GetRegisterInfoAtIndex(i);
+ RegisterValue rVal;
+ if (ctx.reg_ctx->ReadRegister(rArg, rVal))
+ arg.value = rVal.GetAsUInt64(0, &success);
+ }
+ // arguments passed on the stack
+ else
+ {
+ if (log)
+ log->Printf("%s - reading arguments spilled to stack not implemented", __FUNCTION__);
+ }
+ // fail if we couldn't read this argument
+ if (!success)
+ {
+ if (log)
+ log->Printf("%s - error reading argument: %" PRIu64, __FUNCTION__,
+ uint64_t(i));
+ return false;
+ }
+ }
+ return true;
+}
+
+bool
+GetArgsMipsel(GetArgsCtx &ctx, ArgItem *arg_list, size_t num_args)
+{
+ // number of arguments passed in registers
+ static const uint32_t c_args_in_reg = 4;
+ // register file offset to first argument
+ static const uint32_t c_reg_offset = 4;
+
+ Log *log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE);
+
+ Error error;
+
+ // find offset to arguments on the stack (+16 to skip over a0-a3 shadow space)
+ uint64_t sp = ctx.reg_ctx->GetSP() + 16;
+
+ for (size_t i = 0; i < num_args; ++i)
+ {
+ bool success = false;
+ ArgItem &arg = arg_list[i];
+ // arguments passed in registers
+ if (i < c_args_in_reg)
+ {
+ const RegisterInfo *rArg = ctx.reg_ctx->GetRegisterInfoAtIndex(i + c_reg_offset);
+ RegisterValue rVal;
+ if (ctx.reg_ctx->ReadRegister(rArg, rVal))
+ arg.value = rVal.GetAsUInt64(0, &success);
+ }
+ // arguments passed on the stack
+ else
+ {
+ const size_t arg_size = sizeof(uint32_t);
+ arg.value = 0;
+ size_t bytes_read = ctx.process->ReadMemory(sp, &arg.value, arg_size, error);
+ success = (error.Success() && bytes_read == arg_size);
+ // advance the stack pointer
+ sp += arg_size;
+ }
+ // fail if we couldn't read this argument
+ if (!success)
+ {
+ if (log)
+ log->Printf("%s - error reading argument: %" PRIu64", reason: %s",
+ __FUNCTION__, uint64_t(i), error.AsCString("n/a"));
+ return false;
+ }
+ }
+ return true;
+}
+
+bool
+GetArgsMips64el(GetArgsCtx &ctx, ArgItem *arg_list, size_t num_args)
+{
+ // number of arguments passed in registers
+ static const uint32_t c_args_in_reg = 8;
+ // register file offset to first argument
+ static const uint32_t c_reg_offset = 4;
+
+ Log *log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE);
+
+ Error error;
+
+ // get the current stack pointer
+ uint64_t sp = ctx.reg_ctx->GetSP();
+
+ for (size_t i = 0; i < num_args; ++i)
+ {
+ bool success = false;
+ ArgItem &arg = arg_list[i];
+ // arguments passed in registers
+ if (i < c_args_in_reg)
+ {
+ const RegisterInfo *rArg = ctx.reg_ctx->GetRegisterInfoAtIndex(i + c_reg_offset);
+ RegisterValue rVal;
+ if (ctx.reg_ctx->ReadRegister(rArg, rVal))
+ arg.value = rVal.GetAsUInt64(0, &success);
+ }
+ // arguments passed on the stack
+ else
+ {
+ // get the argument type size
+ const size_t arg_size = sizeof(uint64_t);
+ // clear all 64bits
+ arg.value = 0;
+ // read this argument from memory
+ size_t bytes_read = ctx.process->ReadMemory(sp, &arg.value, arg_size, error);
+ success = (error.Success() && bytes_read == arg_size);
+ // advance the stack pointer
+ sp += arg_size;
+ }
+ // fail if we couldn't read this argument
+ if (!success)
+ {
+ if (log)
+ log->Printf("%s - error reading argument: %" PRIu64", reason: %s",
+ __FUNCTION__, uint64_t(i), error.AsCString("n/a"));
+ return false;
+ }
+ }
+ return true;
+}
+
+bool
+GetArgs(ExecutionContext &context, ArgItem *arg_list, size_t num_args)
+{
+ Log *log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE);
+
+ // verify that we have a target
+ if (!context.GetTargetPtr())
+ {
+ if (log)
+ log->Printf("%s - invalid target", __FUNCTION__);
+ return false;
+ }
+
+ GetArgsCtx ctx = {context.GetRegisterContext(), context.GetProcessPtr()};
+ assert(ctx.reg_ctx && ctx.process);
+
+ // dispatch based on architecture
+ switch (context.GetTargetPtr()->GetArchitecture().GetMachine())
+ {
+ case llvm::Triple::ArchType::x86:
+ return GetArgsX86(ctx, arg_list, num_args);
+
+ case llvm::Triple::ArchType::x86_64:
+ return GetArgsX86_64(ctx, arg_list, num_args);
+
+ case llvm::Triple::ArchType::arm:
+ return GetArgsArm(ctx, arg_list, num_args);
+
+ case llvm::Triple::ArchType::aarch64:
+ return GetArgsAarch64(ctx, arg_list, num_args);
+
+ case llvm::Triple::ArchType::mipsel:
+ return GetArgsMipsel(ctx, arg_list, num_args);
+
+ case llvm::Triple::ArchType::mips64el:
+ return GetArgsMips64el(ctx, arg_list, num_args);
+
+ default:
+ // unsupported architecture
+ if (log)
+ {
+ log->Printf("%s - architecture not supported: '%s'", __FUNCTION__,
+ context.GetTargetRef().GetArchitecture().GetArchitectureName());
+ }
+ return false;
+ }
+}
} // anonymous namespace
// The ScriptDetails class collects data associated with a single script instance.
@@ -193,21 +569,23 @@ struct RenderScriptRuntime::Element
RS_TYPE_INVALID = 10000
};
- std::vector<Element> children; // Child Element fields for structs
- empirical_type<lldb::addr_t> element_ptr; // Pointer to the RS Element of the Type
- empirical_type<DataType> type; // Type of each data pointer stored by the allocation
- empirical_type<DataKind> type_kind; // Defines pixel type if Allocation is created from an image
- empirical_type<uint32_t> type_vec_size; // Vector size of each data point, e.g '4' for uchar4
- empirical_type<uint32_t> field_count; // Number of Subelements
- empirical_type<uint32_t> datum_size; // Size of a single Element with padding
- empirical_type<uint32_t> padding; // Number of padding bytes
- empirical_type<uint32_t> array_size; // Number of items in array, only needed for strucrs
- ConstString type_name; // Name of type, only needed for structs
-
- static const ConstString &GetFallbackStructName(); // Print this as the type name of a struct Element
- // If we can't resolve the actual struct name
+ std::vector<Element> children; // Child Element fields for structs
+ empirical_type<lldb::addr_t> element_ptr; // Pointer to the RS Element of the Type
+ empirical_type<DataType> type; // Type of each data pointer stored by the allocation
+ empirical_type<DataKind> type_kind; // Defines pixel type if Allocation is created from an image
+ empirical_type<uint32_t> type_vec_size; // Vector size of each data point, e.g '4' for uchar4
+ empirical_type<uint32_t> field_count; // Number of Subelements
+ empirical_type<uint32_t> datum_size; // Size of a single Element with padding
+ empirical_type<uint32_t> padding; // Number of padding bytes
+ empirical_type<uint32_t> array_size; // Number of items in array, only needed for strucrs
+ ConstString type_name; // Name of type, only needed for structs
+
+ static const ConstString &
+ GetFallbackStructName(); // Print this as the type name of a struct Element
+ // If we can't resolve the actual struct name
- bool shouldRefresh() const
+ bool
+ shouldRefresh() const
{
const bool valid_ptr = element_ptr.isValid() && *element_ptr.get() != 0x0;
const bool valid_type = type.isValid() && type_vec_size.isValid() && type_kind.isValid();
@@ -228,10 +606,10 @@ struct RenderScriptRuntime::AllocationDetails
Dimension()
{
- dim_1 = 0;
- dim_2 = 0;
- dim_3 = 0;
- cubeMap = 0;
+ dim_1 = 0;
+ dim_2 = 0;
+ dim_3 = 0;
+ cubeMap = 0;
}
};
@@ -245,52 +623,51 @@ struct RenderScriptRuntime::AllocationDetails
// These offsets are 4 bytes in size, and the 0 offset signifies no more children.
struct FileHeader
{
- uint8_t ident[4]; // ASCII 'RSAD' identifying the file
- uint32_t dims[3]; // Dimensions
- uint16_t hdr_size; // Header size in bytes, including all element headers
+ uint8_t ident[4]; // ASCII 'RSAD' identifying the file
+ uint32_t dims[3]; // Dimensions
+ uint16_t hdr_size; // Header size in bytes, including all element headers
};
struct ElementHeader
{
- uint16_t type; // DataType enum
- uint32_t kind; // DataKind enum
- uint32_t element_size; // Size of a single element, including padding
- uint16_t vector_size; // Vector width
- uint32_t array_size; // Number of elements in array
+ uint16_t type; // DataType enum
+ uint32_t kind; // DataKind enum
+ uint32_t element_size; // Size of a single element, including padding
+ uint16_t vector_size; // Vector width
+ uint32_t array_size; // Number of elements in array
};
// Monotonically increasing from 1
- static unsigned int ID;
+ static uint32_t ID;
// Maps Allocation DataType enum and vector size to printable strings
// using mapping from RenderScript numerical types summary documentation
- static const char* RsDataTypeToString[][4];
+ static const char *RsDataTypeToString[][4];
// Maps Allocation DataKind enum to printable strings
- static const char* RsDataKindToString[];
+ static const char *RsDataKindToString[];
// Maps allocation types to format sizes for printing.
- static const unsigned int RSTypeToFormat[][3];
+ static const uint32_t RSTypeToFormat[][3];
// Give each allocation an ID as a way
// for commands to reference it.
- const unsigned int id;
+ const uint32_t id;
- RenderScriptRuntime::Element element; // Allocation Element type
- empirical_type<Dimension> dimension; // Dimensions of the Allocation
- empirical_type<lldb::addr_t> address; // Pointer to address of the RS Allocation
- empirical_type<lldb::addr_t> data_ptr; // Pointer to the data held by the Allocation
- empirical_type<lldb::addr_t> type_ptr; // Pointer to the RS Type of the Allocation
- empirical_type<lldb::addr_t> context; // Pointer to the RS Context of the Allocation
- empirical_type<uint32_t> size; // Size of the allocation
- empirical_type<uint32_t> stride; // Stride between rows of the allocation
+ RenderScriptRuntime::Element element; // Allocation Element type
+ empirical_type<Dimension> dimension; // Dimensions of the Allocation
+ empirical_type<lldb::addr_t> address; // Pointer to address of the RS Allocation
+ empirical_type<lldb::addr_t> data_ptr; // Pointer to the data held by the Allocation
+ empirical_type<lldb::addr_t> type_ptr; // Pointer to the RS Type of the Allocation
+ empirical_type<lldb::addr_t> context; // Pointer to the RS Context of the Allocation
+ empirical_type<uint32_t> size; // Size of the allocation
+ empirical_type<uint32_t> stride; // Stride between rows of the allocation
// Give each allocation an id, so we can reference it in user commands.
- AllocationDetails(): id(ID++)
- {
- }
+ AllocationDetails() : id(ID++) {}
- bool shouldRefresh() const
+ bool
+ shouldRefresh() const
{
bool valid_ptrs = data_ptr.isValid() && *data_ptr.get() != 0x0;
valid_ptrs = valid_ptrs && type_ptr.isValid() && *type_ptr.get() != 0x0;
@@ -305,24 +682,15 @@ RenderScriptRuntime::Element::GetFallbackStructName()
return FallbackStructName;
}
-unsigned int RenderScriptRuntime::AllocationDetails::ID = 1;
+uint32_t RenderScriptRuntime::AllocationDetails::ID = 1;
-const char* RenderScriptRuntime::AllocationDetails::RsDataKindToString[] =
-{
- "User",
- "Undefined", "Undefined", "Undefined", // Enum jumps from 0 to 7
- "Undefined", "Undefined", "Undefined",
- "L Pixel",
- "A Pixel",
- "LA Pixel",
- "RGB Pixel",
- "RGBA Pixel",
- "Pixel Depth",
- "YUV Pixel"
-};
+const char *RenderScriptRuntime::AllocationDetails::RsDataKindToString[] = {
+ "User",
+ "Undefined", "Undefined", "Undefined", "Undefined", "Undefined", "Undefined", // Enum jumps from 0 to 7
+ "L Pixel", "A Pixel", "LA Pixel", "RGB Pixel",
+ "RGBA Pixel", "Pixel Depth", "YUV Pixel"};
-const char* RenderScriptRuntime::AllocationDetails::RsDataTypeToString[][4] =
-{
+const char *RenderScriptRuntime::AllocationDetails::RsDataTypeToString[][4] = {
{"None", "None", "None", "None"},
{"half", "half2", "half3", "half4"},
{"float", "float2", "float3", "float4"},
@@ -356,38 +724,37 @@ const char* RenderScriptRuntime::AllocationDetails::RsDataTypeToString[][4] =
{"RS Program Vertex", "RS Program Vertex", "RS Program Vertex", "RS Program Vertex"},
{"RS Program Raster", "RS Program Raster", "RS Program Raster", "RS Program Raster"},
{"RS Program Store", "RS Program Store", "RS Program Store", "RS Program Store"},
- {"RS Font", "RS Font", "RS Font", "RS Font"}
-};
+ {"RS Font", "RS Font", "RS Font", "RS Font"}};
// Used as an index into the RSTypeToFormat array elements
-enum TypeToFormatIndex {
- eFormatSingle = 0,
- eFormatVector,
- eElementSize
+enum TypeToFormatIndex
+{
+ eFormatSingle = 0,
+ eFormatVector,
+ eElementSize
};
// { format enum of single element, format enum of element vector, size of element}
-const unsigned int RenderScriptRuntime::AllocationDetails::RSTypeToFormat[][3] =
-{
- {eFormatHex, eFormatHex, 1}, // RS_TYPE_NONE
- {eFormatFloat, eFormatVectorOfFloat16, 2}, // RS_TYPE_FLOAT_16
- {eFormatFloat, eFormatVectorOfFloat32, sizeof(float)}, // RS_TYPE_FLOAT_32
- {eFormatFloat, eFormatVectorOfFloat64, sizeof(double)}, // RS_TYPE_FLOAT_64
- {eFormatDecimal, eFormatVectorOfSInt8, sizeof(int8_t)}, // RS_TYPE_SIGNED_8
- {eFormatDecimal, eFormatVectorOfSInt16, sizeof(int16_t)}, // RS_TYPE_SIGNED_16
- {eFormatDecimal, eFormatVectorOfSInt32, sizeof(int32_t)}, // RS_TYPE_SIGNED_32
- {eFormatDecimal, eFormatVectorOfSInt64, sizeof(int64_t)}, // RS_TYPE_SIGNED_64
- {eFormatDecimal, eFormatVectorOfUInt8, sizeof(uint8_t)}, // RS_TYPE_UNSIGNED_8
- {eFormatDecimal, eFormatVectorOfUInt16, sizeof(uint16_t)}, // RS_TYPE_UNSIGNED_16
- {eFormatDecimal, eFormatVectorOfUInt32, sizeof(uint32_t)}, // RS_TYPE_UNSIGNED_32
- {eFormatDecimal, eFormatVectorOfUInt64, sizeof(uint64_t)}, // RS_TYPE_UNSIGNED_64
- {eFormatBoolean, eFormatBoolean, 1}, // RS_TYPE_BOOL
- {eFormatHex, eFormatHex, sizeof(uint16_t)}, // RS_TYPE_UNSIGNED_5_6_5
- {eFormatHex, eFormatHex, sizeof(uint16_t)}, // RS_TYPE_UNSIGNED_5_5_5_1
- {eFormatHex, eFormatHex, sizeof(uint16_t)}, // RS_TYPE_UNSIGNED_4_4_4_4
+const uint32_t RenderScriptRuntime::AllocationDetails::RSTypeToFormat[][3] = {
+ {eFormatHex, eFormatHex, 1}, // RS_TYPE_NONE
+ {eFormatFloat, eFormatVectorOfFloat16, 2}, // RS_TYPE_FLOAT_16
+ {eFormatFloat, eFormatVectorOfFloat32, sizeof(float)}, // RS_TYPE_FLOAT_32
+ {eFormatFloat, eFormatVectorOfFloat64, sizeof(double)}, // RS_TYPE_FLOAT_64
+ {eFormatDecimal, eFormatVectorOfSInt8, sizeof(int8_t)}, // RS_TYPE_SIGNED_8
+ {eFormatDecimal, eFormatVectorOfSInt16, sizeof(int16_t)}, // RS_TYPE_SIGNED_16
+ {eFormatDecimal, eFormatVectorOfSInt32, sizeof(int32_t)}, // RS_TYPE_SIGNED_32
+ {eFormatDecimal, eFormatVectorOfSInt64, sizeof(int64_t)}, // RS_TYPE_SIGNED_64
+ {eFormatDecimal, eFormatVectorOfUInt8, sizeof(uint8_t)}, // RS_TYPE_UNSIGNED_8
+ {eFormatDecimal, eFormatVectorOfUInt16, sizeof(uint16_t)}, // RS_TYPE_UNSIGNED_16
+ {eFormatDecimal, eFormatVectorOfUInt32, sizeof(uint32_t)}, // RS_TYPE_UNSIGNED_32
+ {eFormatDecimal, eFormatVectorOfUInt64, sizeof(uint64_t)}, // RS_TYPE_UNSIGNED_64
+ {eFormatBoolean, eFormatBoolean, 1}, // RS_TYPE_BOOL
+ {eFormatHex, eFormatHex, sizeof(uint16_t)}, // RS_TYPE_UNSIGNED_5_6_5
+ {eFormatHex, eFormatHex, sizeof(uint16_t)}, // RS_TYPE_UNSIGNED_5_5_5_1
+ {eFormatHex, eFormatHex, sizeof(uint16_t)}, // RS_TYPE_UNSIGNED_4_4_4_4
{eFormatVectorOfFloat32, eFormatVectorOfFloat32, sizeof(float) * 16}, // RS_TYPE_MATRIX_4X4
- {eFormatVectorOfFloat32, eFormatVectorOfFloat32, sizeof(float) * 9}, // RS_TYPE_MATRIX_3X3
- {eFormatVectorOfFloat32, eFormatVectorOfFloat32, sizeof(float) * 4} // RS_TYPE_MATRIX_2X2
+ {eFormatVectorOfFloat32, eFormatVectorOfFloat32, sizeof(float) * 9}, // RS_TYPE_MATRIX_3X3
+ {eFormatVectorOfFloat32, eFormatVectorOfFloat32, sizeof(float) * 4} // RS_TYPE_MATRIX_2X2
};
//------------------------------------------------------------------
@@ -400,7 +767,7 @@ RenderScriptRuntime::CreateInstance(Process *process, lldb::LanguageType languag
if (language == eLanguageTypeExtRenderScript)
return new RenderScriptRuntime(process);
else
- return NULL;
+ return nullptr;
}
// Callback with a module to search for matching symbols.
@@ -408,10 +775,7 @@ RenderScriptRuntime::CreateInstance(Process *process, lldb::LanguageType languag
// Then look for a symbol which matches our kernel name.
// The breakpoint address is finally set using the address of this symbol.
Searcher::CallbackReturn
-RSBreakpointResolver::SearchCallback(SearchFilter &filter,
- SymbolContext &context,
- Address*,
- bool)
+RSBreakpointResolver::SearchCallback(SearchFilter &filter, SymbolContext &context, Address *, bool)
{
ModuleSP module = context.module_sp;
@@ -426,7 +790,7 @@ RSBreakpointResolver::SearchCallback(SearchFilter &filter,
// If it's not found, it's likely debug info is unavailable - try to set a
// breakpoint on <name>.expand.
- const Symbol* kernel_sym = module->FindFirstSymbolWithNameAndType(m_kernel_name, eSymbolTypeCode);
+ const Symbol *kernel_sym = module->FindFirstSymbolWithNameAndType(m_kernel_name, eSymbolTypeCode);
if (!kernel_sym)
{
std::string kernel_name_expanded(m_kernel_name.AsCString());
@@ -447,7 +811,8 @@ RSBreakpointResolver::SearchCallback(SearchFilter &filter,
void
RenderScriptRuntime::Initialize()
{
- PluginManager::RegisterPlugin(GetPluginNameStatic(), "RenderScript language support", CreateInstance, GetCommandObject);
+ PluginManager::RegisterPlugin(GetPluginNameStatic(), "RenderScript language support", CreateInstance,
+ GetCommandObject);
}
void
@@ -493,7 +858,6 @@ RenderScriptRuntime::GetModuleKind(const lldb::ModuleSP &module_sp)
{
return eModuleKindImpl;
}
-
}
return eModuleKindIgnored;
}
@@ -505,15 +869,15 @@ RenderScriptRuntime::IsRenderScriptModule(const lldb::ModuleSP &module_sp)
}
void
-RenderScriptRuntime::ModulesDidLoad(const ModuleList &module_list )
+RenderScriptRuntime::ModulesDidLoad(const ModuleList &module_list)
{
- Mutex::Locker locker (module_list.GetMutex ());
+ std::lock_guard<std::recursive_mutex> guard(module_list.GetMutex());
size_t num_modules = module_list.GetSize();
for (size_t i = 0; i < num_modules; i++)
{
- auto mod = module_list.GetModuleAtIndex (i);
- if (IsRenderScriptModule (mod))
+ auto mod = module_list.GetModuleAtIndex(i);
+ if (IsRenderScriptModule(mod))
{
LoadModule(mod);
}
@@ -550,8 +914,7 @@ RenderScriptRuntime::GetDynamicTypeAndAddress(ValueObject &in_value, lldb::Dynam
}
TypeAndOrName
-RenderScriptRuntime::FixUpDynamicType (const TypeAndOrName& type_and_or_name,
- ValueObject& static_value)
+RenderScriptRuntime::FixUpDynamicType(const TypeAndOrName &type_and_or_name, ValueObject &static_value)
{
return type_and_or_name;
}
@@ -569,86 +932,71 @@ RenderScriptRuntime::CreateExceptionResolver(Breakpoint *bkpt, bool catch_bp, bo
return resolver_sp;
}
-const RenderScriptRuntime::HookDefn RenderScriptRuntime::s_runtimeHookDefns[] =
-{
- //rsdScript
- {
- "rsdScriptInit", //name
- "_Z13rsdScriptInitPKN7android12renderscript7ContextEPNS0_7ScriptCEPKcS7_PKhjj", // symbol name 32 bit
- "_Z13rsdScriptInitPKN7android12renderscript7ContextEPNS0_7ScriptCEPKcS7_PKhmj", // symbol name 64 bit
- 0, // version
- RenderScriptRuntime::eModuleKindDriver, // type
- &lldb_private::RenderScriptRuntime::CaptureScriptInit1 // handler
- },
- {
- "rsdScriptInvokeForEach", // name
- "_Z22rsdScriptInvokeForEachPKN7android12renderscript7ContextEPNS0_6ScriptEjPKNS0_10AllocationEPS6_PKvjPK12RsScriptCall", // symbol name 32bit
- "_Z22rsdScriptInvokeForEachPKN7android12renderscript7ContextEPNS0_6ScriptEjPKNS0_10AllocationEPS6_PKvmPK12RsScriptCall", // symbol name 64bit
- 0, // version
- RenderScriptRuntime::eModuleKindDriver, // type
- nullptr // handler
- },
+const RenderScriptRuntime::HookDefn RenderScriptRuntime::s_runtimeHookDefns[] = {
+ // rsdScript
{
- "rsdScriptInvokeForEachMulti", // name
- "_Z27rsdScriptInvokeForEachMultiPKN7android12renderscript7ContextEPNS0_6ScriptEjPPKNS0_10AllocationEjPS6_PKvjPK12RsScriptCall", // symbol name 32bit
- "_Z27rsdScriptInvokeForEachMultiPKN7android12renderscript7ContextEPNS0_6ScriptEjPPKNS0_10AllocationEmPS6_PKvmPK12RsScriptCall", // symbol name 64bit
- 0, // version
- RenderScriptRuntime::eModuleKindDriver, // type
- nullptr // handler
+ "rsdScriptInit",
+ "_Z13rsdScriptInitPKN7android12renderscript7ContextEPNS0_7ScriptCEPKcS7_PKhjj",
+ "_Z13rsdScriptInitPKN7android12renderscript7ContextEPNS0_7ScriptCEPKcS7_PKhmj",
+ 0,
+ RenderScriptRuntime::eModuleKindDriver,
+ &lldb_private::RenderScriptRuntime::CaptureScriptInit
},
{
- "rsdScriptInvokeFunction", // name
- "_Z23rsdScriptInvokeFunctionPKN7android12renderscript7ContextEPNS0_6ScriptEjPKvj", // symbol name 32bit
- "_Z23rsdScriptInvokeFunctionPKN7android12renderscript7ContextEPNS0_6ScriptEjPKvm", // symbol name 64bit
- 0, // version
- RenderScriptRuntime::eModuleKindDriver, // type
- nullptr // handler
+ "rsdScriptInvokeForEachMulti",
+ "_Z27rsdScriptInvokeForEachMultiPKN7android12renderscript7ContextEPNS0_6ScriptEjPPKNS0_10AllocationEjPS6_PKvjPK12RsScriptCall",
+ "_Z27rsdScriptInvokeForEachMultiPKN7android12renderscript7ContextEPNS0_6ScriptEjPPKNS0_10AllocationEmPS6_PKvmPK12RsScriptCall",
+ 0,
+ RenderScriptRuntime::eModuleKindDriver,
+ &lldb_private::RenderScriptRuntime::CaptureScriptInvokeForEachMulti
},
{
- "rsdScriptSetGlobalVar", // name
- "_Z21rsdScriptSetGlobalVarPKN7android12renderscript7ContextEPKNS0_6ScriptEjPvj", // symbol name 32bit
- "_Z21rsdScriptSetGlobalVarPKN7android12renderscript7ContextEPKNS0_6ScriptEjPvm", // symbol name 64bit
- 0, // version
- RenderScriptRuntime::eModuleKindDriver, // type
- &lldb_private::RenderScriptRuntime::CaptureSetGlobalVar1 // handler
+ "rsdScriptSetGlobalVar",
+ "_Z21rsdScriptSetGlobalVarPKN7android12renderscript7ContextEPKNS0_6ScriptEjPvj",
+ "_Z21rsdScriptSetGlobalVarPKN7android12renderscript7ContextEPKNS0_6ScriptEjPvm",
+ 0,
+ RenderScriptRuntime::eModuleKindDriver,
+ &lldb_private::RenderScriptRuntime::CaptureSetGlobalVar
},
- //rsdAllocation
+ // rsdAllocation
{
- "rsdAllocationInit", // name
- "_Z17rsdAllocationInitPKN7android12renderscript7ContextEPNS0_10AllocationEb", // symbol name 32bit
- "_Z17rsdAllocationInitPKN7android12renderscript7ContextEPNS0_10AllocationEb", // symbol name 64bit
- 0, // version
- RenderScriptRuntime::eModuleKindDriver, // type
- &lldb_private::RenderScriptRuntime::CaptureAllocationInit1 // handler
+ "rsdAllocationInit",
+ "_Z17rsdAllocationInitPKN7android12renderscript7ContextEPNS0_10AllocationEb",
+ "_Z17rsdAllocationInitPKN7android12renderscript7ContextEPNS0_10AllocationEb",
+ 0,
+ RenderScriptRuntime::eModuleKindDriver,
+ &lldb_private::RenderScriptRuntime::CaptureAllocationInit
},
{
- "rsdAllocationRead2D", //name
- "_Z19rsdAllocationRead2DPKN7android12renderscript7ContextEPKNS0_10AllocationEjjj23RsAllocationCubemapFacejjPvjj", // symbol name 32bit
- "_Z19rsdAllocationRead2DPKN7android12renderscript7ContextEPKNS0_10AllocationEjjj23RsAllocationCubemapFacejjPvmm", // symbol name 64bit
- 0, // version
- RenderScriptRuntime::eModuleKindDriver, // type
- nullptr // handler
+ "rsdAllocationRead2D",
+ "_Z19rsdAllocationRead2DPKN7android12renderscript7ContextEPKNS0_10AllocationEjjj23RsAllocationCubemapFacejjPvjj",
+ "_Z19rsdAllocationRead2DPKN7android12renderscript7ContextEPKNS0_10AllocationEjjj23RsAllocationCubemapFacejjPvmm",
+ 0,
+ RenderScriptRuntime::eModuleKindDriver,
+ nullptr
},
{
- "rsdAllocationDestroy", // name
- "_Z20rsdAllocationDestroyPKN7android12renderscript7ContextEPNS0_10AllocationE", // symbol name 32bit
- "_Z20rsdAllocationDestroyPKN7android12renderscript7ContextEPNS0_10AllocationE", // symbol name 64bit
- 0, // version
- RenderScriptRuntime::eModuleKindDriver, // type
- &lldb_private::RenderScriptRuntime::CaptureAllocationDestroy // handler
+ "rsdAllocationDestroy",
+ "_Z20rsdAllocationDestroyPKN7android12renderscript7ContextEPNS0_10AllocationE",
+ "_Z20rsdAllocationDestroyPKN7android12renderscript7ContextEPNS0_10AllocationE",
+ 0,
+ RenderScriptRuntime::eModuleKindDriver,
+ &lldb_private::RenderScriptRuntime::CaptureAllocationDestroy
},
};
-const size_t RenderScriptRuntime::s_runtimeHookCount = sizeof(s_runtimeHookDefns)/sizeof(s_runtimeHookDefns[0]);
+const size_t RenderScriptRuntime::s_runtimeHookCount = sizeof(s_runtimeHookDefns) / sizeof(s_runtimeHookDefns[0]);
bool
-RenderScriptRuntime::HookCallback(void *baton, StoppointCallbackContext *ctx, lldb::user_id_t break_id, lldb::user_id_t break_loc_id)
+RenderScriptRuntime::HookCallback(void *baton, StoppointCallbackContext *ctx, lldb::user_id_t break_id,
+ lldb::user_id_t break_loc_id)
{
- RuntimeHook* hook_info = (RuntimeHook*)baton;
+ RuntimeHook *hook_info = (RuntimeHook *)baton;
ExecutionContext context(ctx->exe_ctx_ref);
- RenderScriptRuntime *lang_rt = (RenderScriptRuntime *)context.GetProcessPtr()->GetLanguageRuntime(eLanguageTypeExtRenderScript);
+ RenderScriptRuntime *lang_rt =
+ (RenderScriptRuntime *)context.GetProcessPtr()->GetLanguageRuntime(eLanguageTypeExtRenderScript);
lang_rt->HookCallback(hook_info, context);
@@ -656,12 +1004,12 @@ RenderScriptRuntime::HookCallback(void *baton, StoppointCallbackContext *ctx, ll
}
void
-RenderScriptRuntime::HookCallback(RuntimeHook* hook_info, ExecutionContext& context)
+RenderScriptRuntime::HookCallback(RuntimeHook *hook_info, ExecutionContext &context)
{
- Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
if (log)
- log->Printf ("RenderScriptRuntime::HookCallback - '%s' .", hook_info->defn->name);
+ log->Printf("%s - '%s'", __FUNCTION__, hook_info->defn->name);
if (hook_info->defn->grabber)
{
@@ -669,435 +1017,320 @@ RenderScriptRuntime::HookCallback(RuntimeHook* hook_info, ExecutionContext& cont
}
}
-bool
-RenderScriptRuntime::GetArgSimple(ExecutionContext &context, uint32_t arg, uint64_t *data)
-{
- // Get a positional integer argument.
- // Given an ExecutionContext, ``context`` which should be a RenderScript
- // frame, get the value of the positional argument ``arg`` and save its value
- // to the address pointed to by ``data``.
- // returns true on success, false otherwise.
- // If unsuccessful, the value pointed to by ``data`` is undefined. Otherwise,
- // ``data`` will be set to the value of the the given ``arg``.
- // NOTE: only natural width integer arguments for the machine are supported.
- // Behaviour with non primitive arguments is undefined.
-
- if (!data)
- return false;
-
+void
+RenderScriptRuntime::CaptureScriptInvokeForEachMulti(RuntimeHook* hook_info,
+ ExecutionContext& context)
+{
Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
- Error error;
- RegisterContext* reg_ctx = context.GetRegisterContext();
- Process* process = context.GetProcessPtr();
- bool success = false; // return value
- if (!context.GetTargetPtr())
+ enum
+ {
+ eRsContext = 0,
+ eRsScript,
+ eRsSlot,
+ eRsAIns,
+ eRsInLen,
+ eRsAOut,
+ eRsUsr,
+ eRsUsrLen,
+ eRsSc,
+ };
+
+ std::array<ArgItem, 9> args{{
+ ArgItem{ArgItem::ePointer, 0}, // const Context *rsc
+ ArgItem{ArgItem::ePointer, 0}, // Script *s
+ ArgItem{ArgItem::eInt32, 0}, // uint32_t slot
+ ArgItem{ArgItem::ePointer, 0}, // const Allocation **aIns
+ ArgItem{ArgItem::eInt32, 0}, // size_t inLen
+ ArgItem{ArgItem::ePointer, 0}, // Allocation *aout
+ ArgItem{ArgItem::ePointer, 0}, // const void *usr
+ ArgItem{ArgItem::eInt32, 0}, // size_t usrLen
+ ArgItem{ArgItem::ePointer, 0}, // const RsScriptCall *sc
+ }};
+
+ bool success = GetArgs(context, &args[0], args.size());
+ if (!success)
{
if (log)
- log->Printf("RenderScriptRuntime::GetArgSimple - Invalid target");
-
- return false;
+ log->Printf("%s - Error while reading the function parameters", __FUNCTION__);
+ return;
}
- switch (context.GetTargetPtr()->GetArchitecture().GetMachine())
+ const uint32_t target_ptr_size = m_process->GetAddressByteSize();
+ Error error;
+ std::vector<uint64_t> allocs;
+
+ // traverse allocation list
+ for (uint64_t i = 0; i < uint64_t(args[eRsInLen]); ++i)
{
- case llvm::Triple::ArchType::x86:
- {
- uint64_t sp = reg_ctx->GetSP();
- uint32_t offset = (1 + arg) * sizeof(uint32_t);
- uint32_t result = 0;
- process->ReadMemory(sp + offset, &result, sizeof(uint32_t), error);
- if (error.Fail())
- {
- if (log)
- log->Printf("RenderScriptRuntime::GetArgSimple - error reading X86 stack: %s.", error.AsCString());
- }
- else
- {
- *data = result;
- success = true;
- }
- break;
- }
- case llvm::Triple::ArchType::x86_64:
+ // calculate offest to allocation pointer
+ const addr_t addr = addr_t(args[eRsAIns]) + i * target_ptr_size;
+
+ // Note: due to little endian layout, reading 32bits or 64bits into res64 will
+ // give the correct results.
+
+ uint64_t res64 = 0;
+ size_t read = m_process->ReadMemory(addr, &res64, target_ptr_size, error);
+ if (read != target_ptr_size || !error.Success())
{
- // amd64 has 6 integer registers, and 8 XMM registers for parameter passing.
- // Surplus args are spilled onto the stack.
- // rdi, rsi, rdx, rcx, r8, r9, (zmm0 - 7 for vectors)
- // ref: AMD64 ABI Draft 0.99.6 – October 7, 2013 – 10:35; Figure 3.4. Retrieved from
- // http://www.x86-64.org/documentation/abi.pdf
- if (arg > 5)
- {
- if (log)
- log->Warning("X86_64 register spill is not supported.");
- break;
- }
- const char * regnames[] = {"rdi", "rsi", "rdx", "rcx", "r8", "r9"};
- assert((sizeof(regnames) / sizeof(const char *)) > arg);
- const RegisterInfo *rArg = reg_ctx->GetRegisterInfoByName(regnames[arg]);
- RegisterValue rVal;
- success = reg_ctx->ReadRegister(rArg, rVal);
- if (success)
- {
- *data = rVal.GetAsUInt64(0u, &success);
- }
- else
- {
- if (log)
- log->Printf("RenderScriptRuntime::GetArgSimple - error reading x86_64 register: %d.", arg);
- }
- break;
+ if (log)
+ log->Printf("%s - Error while reading allocation list argument %" PRIu64, __FUNCTION__, i);
}
- case llvm::Triple::ArchType::arm:
+ else
{
- // arm 32 bit
- // first 4 arguments are passed via registers
- if (arg < 4)
- {
- const RegisterInfo* rArg = reg_ctx->GetRegisterInfoAtIndex(arg);
- RegisterValue rVal;
- success = reg_ctx->ReadRegister(rArg, rVal);
- if (success)
- {
- (*data) = rVal.GetAsUInt32(0u, &success);
- }
- else
- {
- if (log)
- log->Printf("RenderScriptRuntime::GetArgSimple - error reading ARM register: %d.", arg);
- }
- }
- else
- {
- uint64_t sp = reg_ctx->GetSP();
- uint32_t offset = (arg-4) * sizeof(uint32_t);
- uint32_t value = 0;
- size_t bytes_read = process->ReadMemory(sp + offset, &value, sizeof(value), error);
- if (error.Fail() || bytes_read != sizeof(value))
- {
- if (log)
- log->Printf("RenderScriptRuntime::GetArgSimple - error reading ARM stack: %s.", error.AsCString());
- }
- else
- {
- *data = value;
- success = true;
- }
- }
- break;
+ allocs.push_back(res64);
}
- case llvm::Triple::ArchType::aarch64:
+ }
+
+ // if there is an output allocation track it
+ if (uint64_t aOut = uint64_t(args[eRsAOut]))
+ {
+ allocs.push_back(aOut);
+ }
+
+ // for all allocations we have found
+ for (const uint64_t alloc_addr : allocs)
+ {
+ AllocationDetails* alloc = LookUpAllocation(alloc_addr, true);
+ if (alloc)
{
- // arm 64 bit
- // first 8 arguments are in the registers
- if (arg < 8)
+ // save the allocation address
+ if (alloc->address.isValid())
{
- const RegisterInfo* rArg = reg_ctx->GetRegisterInfoAtIndex(arg);
- RegisterValue rVal;
- success = reg_ctx->ReadRegister(rArg, rVal);
- if (success)
- {
- *data = rVal.GetAsUInt64(0u, &success);
- }
- else
- {
- if (log)
- log->Printf("RenderScriptRuntime::GetArgSimple() - AARCH64 - Error while reading the argument #%d", arg);
- }
+ // check the allocation address we already have matches
+ assert(*alloc->address.get() == alloc_addr);
}
else
{
- // @TODO: need to find the argument in the stack
- if (log)
- log->Printf("RenderScriptRuntime::GetArgSimple - AARCH64 - FOR #ARG >= 8 NOT IMPLEMENTED YET. Argument number: %d", arg);
- }
- break;
- }
- case llvm::Triple::ArchType::mipsel:
- {
- // read from the registers
- // first 4 arguments are passed in registers
- if (arg < 4){
- const RegisterInfo* rArg = reg_ctx->GetRegisterInfoAtIndex(arg + 4);
- RegisterValue rVal;
- success = reg_ctx->ReadRegister(rArg, rVal);
- if (success)
- {
- *data = rVal.GetAsUInt64(0u, &success);
- }
- else
- {
- if (log)
- log->Printf("RenderScriptRuntime::GetArgSimple() - Mips - Error while reading the argument #%d", arg);
- }
- }
- // arguments > 4 are read from the stack
- else
- {
- uint64_t sp = reg_ctx->GetSP();
- uint32_t offset = arg * sizeof(uint32_t);
- uint32_t value = 0;
- size_t bytes_read = process->ReadMemory(sp + offset, &value, sizeof(value), error);
- if (error.Fail() || bytes_read != sizeof(value))
- {
- if (log)
- log->Printf("RenderScriptRuntime::GetArgSimple - error reading Mips stack: %s.", error.AsCString());
- }
- else
- {
- *data = value;
- success = true;
- }
- }
- break;
- }
- case llvm::Triple::ArchType::mips64el:
- {
- // read from the registers
- if (arg < 8)
- {
- const RegisterInfo* rArg = reg_ctx->GetRegisterInfoAtIndex(arg + 4);
- RegisterValue rVal;
- success = reg_ctx->ReadRegister(rArg, rVal);
- if (success)
- {
- (*data) = rVal.GetAsUInt64(0u, &success);
- }
- else
- {
- if (log)
- log->Printf("RenderScriptRuntime::GetArgSimple - Mips64 - Error reading the argument #%d", arg);
- }
+ alloc->address = alloc_addr;
}
- // arguments > 8 are read from the stack
- else
+
+ // save the context
+ if (log)
{
- uint64_t sp = reg_ctx->GetSP();
- uint32_t offset = (arg - 8) * sizeof(uint64_t);
- uint64_t value = 0;
- size_t bytes_read = process->ReadMemory(sp + offset, &value, sizeof(value), error);
- if (error.Fail() || bytes_read != sizeof(value))
- {
- if (log)
- log->Printf("RenderScriptRuntime::GetArgSimple - Mips64 - Error reading Mips64 stack: %s.", error.AsCString());
- }
- else
- {
- *data = value;
- success = true;
- }
+ if (alloc->context.isValid() && *alloc->context.get() != addr_t(args[eRsContext]))
+ log->Printf("%s - Allocation used by multiple contexts", __FUNCTION__);
}
- break;
- }
- default:
- {
- // invalid architecture
- if (log)
- log->Printf("RenderScriptRuntime::GetArgSimple - Architecture not supported");
+ alloc->context = addr_t(args[eRsContext]);
}
}
- if (!success)
+ // make sure we track this script object
+ if (lldb_private::RenderScriptRuntime::ScriptDetails *script = LookUpScript(addr_t(args[eRsScript]), true))
{
if (log)
- log->Printf("RenderScriptRuntime::GetArgSimple - failed to get argument at index %" PRIu32, arg);
+ {
+ if (script->context.isValid() && *script->context.get() != addr_t(args[eRsContext]))
+ log->Printf("%s - Script used by multiple contexts", __FUNCTION__);
+ }
+ script->context = addr_t(args[eRsContext]);
}
- return success;
}
void
-RenderScriptRuntime::CaptureSetGlobalVar1(RuntimeHook* hook_info, ExecutionContext& context)
+RenderScriptRuntime::CaptureSetGlobalVar(RuntimeHook *hook_info, ExecutionContext &context)
{
- Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
- //Context, Script, int, data, length
-
- uint64_t rs_context_u64 = 0U;
- uint64_t rs_script_u64 = 0U;
- uint64_t rs_id_u64 = 0U;
- uint64_t rs_data_u64 = 0U;
- uint64_t rs_length_u64 = 0U;
+ enum
+ {
+ eRsContext,
+ eRsScript,
+ eRsId,
+ eRsData,
+ eRsLength,
+ };
- bool success =
- GetArgSimple(context, 0, &rs_context_u64) &&
- GetArgSimple(context, 1, &rs_script_u64) &&
- GetArgSimple(context, 2, &rs_id_u64) &&
- GetArgSimple(context, 3, &rs_data_u64) &&
- GetArgSimple(context, 4, &rs_length_u64);
+ std::array<ArgItem, 5> args{{
+ ArgItem{ArgItem::ePointer, 0}, // eRsContext
+ ArgItem{ArgItem::ePointer, 0}, // eRsScript
+ ArgItem{ArgItem::eInt32, 0}, // eRsId
+ ArgItem{ArgItem::ePointer, 0}, // eRsData
+ ArgItem{ArgItem::eInt32, 0}, // eRsLength
+ }};
+ bool success = GetArgs(context, &args[0], args.size());
if (!success)
{
if (log)
- log->Printf("RenderScriptRuntime::CaptureSetGlobalVar1 - Error while reading the function parameters");
+ log->Printf("%s - error reading the function parameters.", __FUNCTION__);
return;
}
if (log)
{
- log->Printf ("RenderScriptRuntime::CaptureSetGlobalVar1 - 0x%" PRIx64 ",0x%" PRIx64 " slot %" PRIu64 " = 0x%" PRIx64 ":%" PRIu64 "bytes.",
- rs_context_u64, rs_script_u64, rs_id_u64, rs_data_u64, rs_length_u64);
+ log->Printf("%s - 0x%" PRIx64 ",0x%" PRIx64 " slot %" PRIu64 " = 0x%" PRIx64 ":%" PRIu64 "bytes.", __FUNCTION__,
+ uint64_t(args[eRsContext]), uint64_t(args[eRsScript]), uint64_t(args[eRsId]),
+ uint64_t(args[eRsData]), uint64_t(args[eRsLength]));
- addr_t script_addr = (addr_t)rs_script_u64;
- if (m_scriptMappings.find( script_addr ) != m_scriptMappings.end())
+ addr_t script_addr = addr_t(args[eRsScript]);
+ if (m_scriptMappings.find(script_addr) != m_scriptMappings.end())
{
auto rsm = m_scriptMappings[script_addr];
- if (rs_id_u64 < rsm->m_globals.size())
+ if (uint64_t(args[eRsId]) < rsm->m_globals.size())
{
- auto rsg = rsm->m_globals[rs_id_u64];
- log->Printf ("RenderScriptRuntime::CaptureSetGlobalVar1 - Setting of '%s' within '%s' inferred", rsg.m_name.AsCString(),
- rsm->m_module->GetFileSpec().GetFilename().AsCString());
+ auto rsg = rsm->m_globals[uint64_t(args[eRsId])];
+ log->Printf("%s - Setting of '%s' within '%s' inferred", __FUNCTION__, rsg.m_name.AsCString(),
+ rsm->m_module->GetFileSpec().GetFilename().AsCString());
}
}
}
}
void
-RenderScriptRuntime::CaptureAllocationInit1(RuntimeHook* hook_info, ExecutionContext& context)
+RenderScriptRuntime::CaptureAllocationInit(RuntimeHook *hook_info, ExecutionContext &context)
{
- Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
- //Context, Alloc, bool
+ enum
+ {
+ eRsContext,
+ eRsAlloc,
+ eRsForceZero
+ };
- uint64_t rs_context_u64 = 0U;
- uint64_t rs_alloc_u64 = 0U;
- uint64_t rs_forceZero_u64 = 0U;
+ std::array<ArgItem, 3> args{{
+ ArgItem{ArgItem::ePointer, 0}, // eRsContext
+ ArgItem{ArgItem::ePointer, 0}, // eRsAlloc
+ ArgItem{ArgItem::eBool, 0}, // eRsForceZero
+ }};
- bool success =
- GetArgSimple(context, 0, &rs_context_u64) &&
- GetArgSimple(context, 1, &rs_alloc_u64) &&
- GetArgSimple(context, 2, &rs_forceZero_u64);
+ bool success = GetArgs(context, &args[0], args.size());
if (!success) // error case
{
if (log)
- log->Printf("RenderScriptRuntime::CaptureAllocationInit1 - Error while reading the function parameters");
+ log->Printf("%s - error while reading the function parameters", __FUNCTION__);
return; // abort
}
if (log)
- log->Printf ("RenderScriptRuntime::CaptureAllocationInit1 - 0x%" PRIx64 ",0x%" PRIx64 ",0x%" PRIx64 " .",
- rs_context_u64, rs_alloc_u64, rs_forceZero_u64);
+ log->Printf("%s - 0x%" PRIx64 ",0x%" PRIx64 ",0x%" PRIx64 " .", __FUNCTION__, uint64_t(args[eRsContext]),
+ uint64_t(args[eRsAlloc]), uint64_t(args[eRsForceZero]));
- AllocationDetails* alloc = LookUpAllocation(rs_alloc_u64, true);
+ AllocationDetails *alloc = LookUpAllocation(uint64_t(args[eRsAlloc]), true);
if (alloc)
- alloc->context = rs_context_u64;
+ alloc->context = uint64_t(args[eRsContext]);
}
void
-RenderScriptRuntime::CaptureAllocationDestroy(RuntimeHook* hook_info, ExecutionContext& context)
+RenderScriptRuntime::CaptureAllocationDestroy(RuntimeHook *hook_info, ExecutionContext &context)
{
- Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
- // Context, Alloc
- uint64_t rs_context_u64 = 0U;
- uint64_t rs_alloc_u64 = 0U;
+ enum
+ {
+ eRsContext,
+ eRsAlloc,
+ };
- bool success = GetArgSimple(context, 0, &rs_context_u64) && GetArgSimple(context, 1, &rs_alloc_u64);
- if (!success) // error case
+ std::array<ArgItem, 2> args{{
+ ArgItem{ArgItem::ePointer, 0}, // eRsContext
+ ArgItem{ArgItem::ePointer, 0}, // eRsAlloc
+ }};
+
+ bool success = GetArgs(context, &args[0], args.size());
+ if (!success)
{
if (log)
- log->Printf("RenderScriptRuntime::CaptureAllocationDestroy - Error while reading the function parameters");
- return; // abort
+ log->Printf("%s - error while reading the function parameters.", __FUNCTION__);
+ return;
}
if (log)
- log->Printf("RenderScriptRuntime::CaptureAllocationDestroy - 0x%" PRIx64 ", 0x%" PRIx64 ".",
- rs_context_u64, rs_alloc_u64);
+ log->Printf("%s - 0x%" PRIx64 ", 0x%" PRIx64 ".", __FUNCTION__, uint64_t(args[eRsContext]),
+ uint64_t(args[eRsAlloc]));
for (auto iter = m_allocations.begin(); iter != m_allocations.end(); ++iter)
{
- auto& allocation_ap = *iter; // get the unique pointer
- if (allocation_ap->address.isValid() && *allocation_ap->address.get() == rs_alloc_u64)
+ auto &allocation_ap = *iter; // get the unique pointer
+ if (allocation_ap->address.isValid() && *allocation_ap->address.get() == addr_t(args[eRsAlloc]))
{
m_allocations.erase(iter);
if (log)
- log->Printf("RenderScriptRuntime::CaptureAllocationDestroy - Deleted allocation entry");
+ log->Printf("%s - deleted allocation entry.", __FUNCTION__);
return;
}
}
if (log)
- log->Printf("RenderScriptRuntime::CaptureAllocationDestroy - Couldn't find destroyed allocation");
+ log->Printf("%s - couldn't find destroyed allocation.", __FUNCTION__);
}
void
-RenderScriptRuntime::CaptureScriptInit1(RuntimeHook* hook_info, ExecutionContext& context)
+RenderScriptRuntime::CaptureScriptInit(RuntimeHook *hook_info, ExecutionContext &context)
{
- Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
- //Context, Script, resname Str, cachedir Str
Error error;
- Process* process = context.GetProcessPtr();
-
- uint64_t rs_context_u64 = 0U;
- uint64_t rs_script_u64 = 0U;
- uint64_t rs_resnameptr_u64 = 0U;
- uint64_t rs_cachedirptr_u64 = 0U;
-
- std::string resname;
- std::string cachedir;
+ Process *process = context.GetProcessPtr();
- // read the function parameters
- bool success =
- GetArgSimple(context, 0, &rs_context_u64) &&
- GetArgSimple(context, 1, &rs_script_u64) &&
- GetArgSimple(context, 2, &rs_resnameptr_u64) &&
- GetArgSimple(context, 3, &rs_cachedirptr_u64);
+ enum
+ {
+ eRsContext,
+ eRsScript,
+ eRsResNamePtr,
+ eRsCachedDirPtr
+ };
+ std::array<ArgItem, 4> args{{ArgItem{ArgItem::ePointer, 0}, ArgItem{ArgItem::ePointer, 0},
+ ArgItem{ArgItem::ePointer, 0}, ArgItem{ArgItem::ePointer, 0}}};
+ bool success = GetArgs(context, &args[0], args.size());
if (!success)
{
if (log)
- log->Printf("RenderScriptRuntime::CaptureScriptInit1 - Error while reading the function parameters");
+ log->Printf("%s - error while reading the function parameters.", __FUNCTION__);
return;
}
- process->ReadCStringFromMemory((lldb::addr_t)rs_resnameptr_u64, resname, error);
+ std::string resname;
+ process->ReadCStringFromMemory(addr_t(args[eRsResNamePtr]), resname, error);
if (error.Fail())
{
if (log)
- log->Printf ("RenderScriptRuntime::CaptureScriptInit1 - error reading resname: %s.", error.AsCString());
-
+ log->Printf("%s - error reading resname: %s.", __FUNCTION__, error.AsCString());
}
- process->ReadCStringFromMemory((lldb::addr_t)rs_cachedirptr_u64, cachedir, error);
+ std::string cachedir;
+ process->ReadCStringFromMemory(addr_t(args[eRsCachedDirPtr]), cachedir, error);
if (error.Fail())
{
if (log)
- log->Printf ("RenderScriptRuntime::CaptureScriptInit1 - error reading cachedir: %s.", error.AsCString());
+ log->Printf("%s - error reading cachedir: %s.", __FUNCTION__, error.AsCString());
}
if (log)
- log->Printf ("RenderScriptRuntime::CaptureScriptInit1 - 0x%" PRIx64 ",0x%" PRIx64 " => '%s' at '%s' .",
- rs_context_u64, rs_script_u64, resname.c_str(), cachedir.c_str());
+ log->Printf("%s - 0x%" PRIx64 ",0x%" PRIx64 " => '%s' at '%s' .", __FUNCTION__, uint64_t(args[eRsContext]),
+ uint64_t(args[eRsScript]), resname.c_str(), cachedir.c_str());
if (resname.size() > 0)
{
StreamString strm;
strm.Printf("librs.%s.so", resname.c_str());
- ScriptDetails* script = LookUpScript(rs_script_u64, true);
+ ScriptDetails *script = LookUpScript(addr_t(args[eRsScript]), true);
if (script)
{
script->type = ScriptDetails::eScriptC;
script->cacheDir = cachedir;
script->resName = resname;
script->scriptDyLib = strm.GetData();
- script->context = addr_t(rs_context_u64);
+ script->context = addr_t(args[eRsContext]);
}
if (log)
- log->Printf ("RenderScriptRuntime::CaptureScriptInit1 - '%s' tagged with context 0x%" PRIx64 " and script 0x%" PRIx64 ".",
- strm.GetData(), rs_context_u64, rs_script_u64);
+ log->Printf("%s - '%s' tagged with context 0x%" PRIx64 " and script 0x%" PRIx64 ".", __FUNCTION__,
+ strm.GetData(), uint64_t(args[eRsContext]), uint64_t(args[eRsScript]));
}
else if (log)
{
- log->Printf ("RenderScriptRuntime::CaptureScriptInit1 - resource name invalid, Script not tagged");
+ log->Printf("%s - resource name invalid, Script not tagged.", __FUNCTION__);
}
}
void
RenderScriptRuntime::LoadRuntimeHooks(lldb::ModuleSP module, ModuleKind kind)
{
- Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
if (!module)
{
@@ -1107,17 +1340,15 @@ RenderScriptRuntime::LoadRuntimeHooks(lldb::ModuleSP module, ModuleKind kind)
Target &target = GetProcess()->GetTarget();
llvm::Triple::ArchType targetArchType = target.GetArchitecture().GetMachine();
- if (targetArchType != llvm::Triple::ArchType::x86
- && targetArchType != llvm::Triple::ArchType::arm
- && targetArchType != llvm::Triple::ArchType::aarch64
- && targetArchType != llvm::Triple::ArchType::mipsel
- && targetArchType != llvm::Triple::ArchType::mips64el
- && targetArchType != llvm::Triple::ArchType::x86_64
- )
+ if (targetArchType != llvm::Triple::ArchType::x86 &&
+ targetArchType != llvm::Triple::ArchType::arm &&
+ targetArchType != llvm::Triple::ArchType::aarch64 &&
+ targetArchType != llvm::Triple::ArchType::mipsel &&
+ targetArchType != llvm::Triple::ArchType::mips64el &&
+ targetArchType != llvm::Triple::ArchType::x86_64)
{
if (log)
- log->Printf ("RenderScriptRuntime::LoadRuntimeHooks - Unable to hook runtime. Only X86, ARM, Mips supported currently.");
-
+ log->Printf("%s - unable to hook runtime functions.", __FUNCTION__);
return;
}
@@ -1125,17 +1356,21 @@ RenderScriptRuntime::LoadRuntimeHooks(lldb::ModuleSP module, ModuleKind kind)
for (size_t idx = 0; idx < s_runtimeHookCount; idx++)
{
- const HookDefn* hook_defn = &s_runtimeHookDefns[idx];
- if (hook_defn->kind != kind) {
+ const HookDefn *hook_defn = &s_runtimeHookDefns[idx];
+ if (hook_defn->kind != kind)
+ {
continue;
}
- const char* symbol_name = (archByteSize == 4) ? hook_defn->symbol_name_m32 : hook_defn->symbol_name_m64;
+ const char *symbol_name = (archByteSize == 4) ? hook_defn->symbol_name_m32 : hook_defn->symbol_name_m64;
const Symbol *sym = module->FindFirstSymbolWithNameAndType(ConstString(symbol_name), eSymbolTypeCode);
- if (!sym){
- if (log){
- log->Printf("RenderScriptRuntime::LoadRuntimeHooks - ERROR: Symbol '%s' related to the function %s not found", symbol_name, hook_defn->name);
+ if (!sym)
+ {
+ if (log)
+ {
+ log->Printf("%s - symbol '%s' related to the function %s not found",
+ __FUNCTION__, symbol_name, hook_defn->name);
}
continue;
}
@@ -1144,14 +1379,15 @@ RenderScriptRuntime::LoadRuntimeHooks(lldb::ModuleSP module, ModuleKind kind)
if (addr == LLDB_INVALID_ADDRESS)
{
if (log)
- log->Printf ("RenderScriptRuntime::LoadRuntimeHooks - Unable to resolve the address of hook function '%s' with symbol '%s'.",
- hook_defn->name, symbol_name);
+ log->Printf("%s - unable to resolve the address of hook function '%s' with symbol '%s'.",
+ __FUNCTION__, hook_defn->name, symbol_name);
continue;
}
else
{
if (log)
- log->Printf("RenderScriptRuntime::LoadRuntimeHooks - Function %s, address resolved at 0x%" PRIx64, hook_defn->name, addr);
+ log->Printf("%s - function %s, address resolved at 0x%" PRIx64,
+ __FUNCTION__, hook_defn->name, addr);
}
RuntimeHookSP hook(new RuntimeHook());
@@ -1162,8 +1398,9 @@ RenderScriptRuntime::LoadRuntimeHooks(lldb::ModuleSP module, ModuleKind kind)
m_runtimeHooks[addr] = hook;
if (log)
{
- log->Printf ("RenderScriptRuntime::LoadRuntimeHooks - Successfully hooked '%s' in '%s' version %" PRIu64 " at 0x%" PRIx64 ".",
- hook_defn->name, module->GetFileSpec().GetFilename().AsCString(), (uint64_t)hook_defn->version, (uint64_t)addr);
+ log->Printf("%s - successfully hooked '%s' in '%s' version %" PRIu64 " at 0x%" PRIx64 ".",
+ __FUNCTION__, hook_defn->name, module->GetFileSpec().GetFilename().AsCString(),
+ (uint64_t)hook_defn->version, (uint64_t)addr);
}
}
}
@@ -1174,14 +1411,14 @@ RenderScriptRuntime::FixupScriptDetails(RSModuleDescriptorSP rsmodule_sp)
if (!rsmodule_sp)
return;
- Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
const ModuleSP module = rsmodule_sp->m_module;
- const FileSpec& file = module->GetPlatformFileSpec();
+ const FileSpec &file = module->GetPlatformFileSpec();
// Iterate over all of the scripts that we currently know of.
// Note: We cant push or pop to m_scripts here or it may invalidate rs_script.
- for (const auto & rs_script : m_scripts)
+ for (const auto &rs_script : m_scripts)
{
// Extract the expected .so file path for this script.
std::string dylib;
@@ -1204,8 +1441,8 @@ RenderScriptRuntime::FixupScriptDetails(RSModuleDescriptorSP rsmodule_sp)
if (m_scriptMappings[script] != rsmodule_sp)
{
if (log)
- log->Printf ("RenderScriptRuntime::FixupScriptDetails - Error: script %" PRIx64 " wants reassigned to new rsmodule '%s'.",
- (uint64_t)script, rsmodule_sp->m_module->GetFileSpec().GetFilename().AsCString());
+ log->Printf("%s - script %" PRIx64 " wants reassigned to new rsmodule '%s'.", __FUNCTION__,
+ (uint64_t)script, rsmodule_sp->m_module->GetFileSpec().GetFilename().AsCString());
}
}
// We don't have a script mapping for the current script.
@@ -1219,8 +1456,8 @@ RenderScriptRuntime::FixupScriptDetails(RSModuleDescriptorSP rsmodule_sp)
// Add Script/Module pair to map.
m_scriptMappings[script] = rsmodule_sp;
if (log)
- log->Printf ("RenderScriptRuntime::FixupScriptDetails - script %" PRIx64 " associated with rsmodule '%s'.",
- (uint64_t)script, rsmodule_sp->m_module->GetFileSpec().GetFilename().AsCString());
+ log->Printf("%s - script %" PRIx64 " associated with rsmodule '%s'.", __FUNCTION__,
+ (uint64_t)script, rsmodule_sp->m_module->GetFileSpec().GetFilename().AsCString());
}
}
}
@@ -1229,21 +1466,23 @@ RenderScriptRuntime::FixupScriptDetails(RSModuleDescriptorSP rsmodule_sp)
// The result of that expression is returned an unsigned 64 bit int, via the result* paramter.
// Function returns true on success, and false on failure
bool
-RenderScriptRuntime::EvalRSExpression(const char* expression, StackFrame* frame_ptr, uint64_t* result)
+RenderScriptRuntime::EvalRSExpression(const char *expression, StackFrame *frame_ptr, uint64_t *result)
{
- Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
if (log)
- log->Printf("RenderScriptRuntime::EvalRSExpression(%s)", expression);
+ log->Printf("%s(%s)", __FUNCTION__, expression);
ValueObjectSP expr_result;
+ EvaluateExpressionOptions options;
+ options.SetLanguage(lldb::eLanguageTypeC_plus_plus);
// Perform the actual expression evaluation
- GetProcess()->GetTarget().EvaluateExpression(expression, frame_ptr, expr_result);
+ GetProcess()->GetTarget().EvaluateExpression(expression, frame_ptr, expr_result, options);
if (!expr_result)
{
- if (log)
- log->Printf("RenderScriptRuntime::EvalRSExpression - Error: Couldn't evaluate expression");
- return false;
+ if (log)
+ log->Printf("%s: couldn't evaluate expression.", __FUNCTION__);
+ return false;
}
// The result of the expression is invalid
@@ -1253,159 +1492,104 @@ RenderScriptRuntime::EvalRSExpression(const char* expression, StackFrame* frame_
if (err.GetError() == UserExpression::kNoResult) // Expression returned void, so this is actually a success
{
if (log)
- log->Printf("RenderScriptRuntime::EvalRSExpression - Expression returned void");
+ log->Printf("%s - expression returned void.", __FUNCTION__);
result = nullptr;
return true;
}
if (log)
- log->Printf("RenderScriptRuntime::EvalRSExpression - Error evaluating expression result: %s", err.AsCString());
+ log->Printf("%s - error evaluating expression result: %s", __FUNCTION__,
+ err.AsCString());
return false;
}
bool success = false;
- *result = expr_result->GetValueAsUnsigned(0, &success); // We only read the result as an unsigned int.
+ *result = expr_result->GetValueAsUnsigned(0, &success); // We only read the result as an uint32_t.
if (!success)
{
- if (log)
- log->Printf("RenderScriptRuntime::EvalRSExpression - Error: Couldn't convert expression result to unsigned int");
- return false;
+ if (log)
+ log->Printf("%s - couldn't convert expression result to uint32_t", __FUNCTION__);
+ return false;
}
return true;
}
-namespace // anonymous
+namespace
+{
+// Used to index expression format strings
+enum ExpressionStrings
{
- // max length of an expanded expression
- const int jit_max_expr_size = 768;
+ eExprGetOffsetPtr = 0,
+ eExprAllocGetType,
+ eExprTypeDimX,
+ eExprTypeDimY,
+ eExprTypeDimZ,
+ eExprTypeElemPtr,
+ eExprElementType,
+ eExprElementKind,
+ eExprElementVec,
+ eExprElementFieldCount,
+ eExprSubelementsId,
+ eExprSubelementsName,
+ eExprSubelementsArrSize,
+
+ _eExprLast // keep at the end, implicit size of the array runtimeExpressions
+};
+
+// max length of an expanded expression
+const int jit_max_expr_size = 512;
+// Retrieve the string to JIT for the given expression
+const char*
+JITTemplate(ExpressionStrings e)
+{
// Format strings containing the expressions we may need to evaluate.
- const char runtimeExpressions[][256] =
- {
+ static std::array<const char*, _eExprLast> runtimeExpressions = {{
// Mangled GetOffsetPointer(Allocation*, xoff, yoff, zoff, lod, cubemap)
- "(int*)_Z12GetOffsetPtrPKN7android12renderscript10AllocationEjjjj23RsAllocationCubemapFace(0x%lx, %u, %u, %u, 0, 0)",
+ "(int*)_Z12GetOffsetPtrPKN7android12renderscript10AllocationEjjjj23RsAllocationCubemapFace"
+ "(0x%" PRIx64 ", %" PRIu32 ", %" PRIu32 ", %" PRIu32 ", 0, 0)",
// Type* rsaAllocationGetType(Context*, Allocation*)
- "(void*)rsaAllocationGetType(0x%lx, 0x%lx)",
+ "(void*)rsaAllocationGetType(0x%" PRIx64 ", 0x%" PRIx64 ")",
// rsaTypeGetNativeData(Context*, Type*, void* typeData, size)
// Pack the data in the following way mHal.state.dimX; mHal.state.dimY; mHal.state.dimZ;
// mHal.state.lodCount; mHal.state.faces; mElement; into typeData
// Need to specify 32 or 64 bit for uint_t since this differs between devices
- "uint%u_t data[6]; (void*)rsaTypeGetNativeData(0x%lx, 0x%lx, data, 6); data[0]", // X dim
- "uint%u_t data[6]; (void*)rsaTypeGetNativeData(0x%lx, 0x%lx, data, 6); data[1]", // Y dim
- "uint%u_t data[6]; (void*)rsaTypeGetNativeData(0x%lx, 0x%lx, data, 6); data[2]", // Z dim
- "uint%u_t data[6]; (void*)rsaTypeGetNativeData(0x%lx, 0x%lx, data, 6); data[5]", // Element ptr
+ "uint%" PRIu32 "_t data[6]; (void*)rsaTypeGetNativeData(0x%" PRIx64 ", 0x%" PRIx64 ", data, 6); data[0]", // X dim
+ "uint%" PRIu32 "_t data[6]; (void*)rsaTypeGetNativeData(0x%" PRIx64 ", 0x%" PRIx64 ", data, 6); data[1]", // Y dim
+ "uint%" PRIu32 "_t data[6]; (void*)rsaTypeGetNativeData(0x%" PRIx64 ", 0x%" PRIx64 ", data, 6); data[2]", // Z dim
+ "uint%" PRIu32 "_t data[6]; (void*)rsaTypeGetNativeData(0x%" PRIx64 ", 0x%" PRIx64 ", data, 6); data[5]", // Element ptr
// rsaElementGetNativeData(Context*, Element*, uint32_t* elemData,size)
// Pack mType; mKind; mNormalized; mVectorSize; NumSubElements into elemData
- "uint32_t data[5]; (void*)rsaElementGetNativeData(0x%lx, 0x%lx, data, 5); data[0]", // Type
- "uint32_t data[5]; (void*)rsaElementGetNativeData(0x%lx, 0x%lx, data, 5); data[1]", // Kind
- "uint32_t data[5]; (void*)rsaElementGetNativeData(0x%lx, 0x%lx, data, 5); data[3]", // Vector Size
- "uint32_t data[5]; (void*)rsaElementGetNativeData(0x%lx, 0x%lx, data, 5); data[4]", // Field Count
-
- // rsaElementGetSubElements(RsContext con, RsElement elem, uintptr_t *ids, const char **names,
- // size_t *arraySizes, uint32_t dataSize)
- // Needed for Allocations of structs to gather details about fields/Subelements
- "void* ids[%u]; const char* names[%u]; size_t arr_size[%u];"
- "(void*)rsaElementGetSubElements(0x%lx, 0x%lx, ids, names, arr_size, %u); ids[%u]", // Element* of field
-
- "void* ids[%u]; const char* names[%u]; size_t arr_size[%u];"
- "(void*)rsaElementGetSubElements(0x%lx, 0x%lx, ids, names, arr_size, %u); names[%u]", // Name of field
-
- "void* ids[%u]; const char* names[%u]; size_t arr_size[%u];"
- "(void*)rsaElementGetSubElements(0x%lx, 0x%lx, ids, names, arr_size, %u); arr_size[%u]" // Array size of field
- };
-
-
- // Temporary workaround for MIPS, until the compiler emits the JAL instruction when invoking directly the function.
- // At the moment, when evaluating an expression involving a function call, the LLVM codegen for Mips emits a JAL
- // instruction, which is able to jump in the range +/- 128MB with respect to the current program counter ($pc). If
- // the requested function happens to reside outside the above region, the function address will be truncated and the
- // function invocation will fail. This is a problem in the RS plugin as we rely on the RS API to probe the number and
- // the nature of allocations. A proper solution in the MIPS compiler is currently being investigated. As temporary
- // work around for this context, we'll invoke the RS API through function pointers, which cause the compiler to emit a
- // register based JALR instruction.
- const char runtimeExpressions_mips[][512] =
- {
- // Mangled GetOffsetPointer(Allocation*, xoff, yoff, zoff, lod, cubemap)
- "int* (*f) (void*, int, int, int, int, int) = (int* (*) (void*, int, int, int, int, int)) "
- "_Z12GetOffsetPtrPKN7android12renderscript10AllocationEjjjj23RsAllocationCubemapFace; "
- "(int*) f((void*) 0x%lx, %u, %u, %u, 0, 0)",
-
- // Type* rsaAllocationGetType(Context*, Allocation*)
- "void* (*f) (void*, void*) = (void* (*) (void*, void*)) rsaAllocationGetType; (void*) f((void*) 0x%lx, (void*) 0x%lx)",
-
- // rsaTypeGetNativeData(Context*, Type*, void* typeData, size)
- // Pack the data in the following way mHal.state.dimX; mHal.state.dimY; mHal.state.dimZ;
- // mHal.state.lodCount; mHal.state.faces; mElement; into typeData
- // Need to specify 32 or 64 bit for uint_t since this differs between devices
- "uint%u_t data[6]; void* (*f)(void*, void*, uintptr_t*, uint32_t) = (void* (*)(void*, void*, uintptr_t*, uint32_t)) "
- "rsaTypeGetNativeData; (void*) f((void*) 0x%lx, (void*) 0x%lx, data, 6); data[0]",
- "uint%u_t data[6]; void* (*f)(void*, void*, uintptr_t*, uint32_t) = (void* (*)(void*, void*, uintptr_t*, uint32_t)) "
- "rsaTypeGetNativeData; (void*) f((void*) 0x%lx, (void*) 0x%lx, data, 6); data[1]",
- "uint%u_t data[6]; void* (*f)(void*, void*, uintptr_t*, uint32_t) = (void* (*)(void*, void*, uintptr_t*, uint32_t)) "
- "rsaTypeGetNativeData; (void*) f((void*) 0x%lx, (void*) 0x%lx, data, 6); data[2]",
- "uint%u_t data[6]; void* (*f)(void*, void*, uintptr_t*, uint32_t) = (void* (*)(void*, void*, uintptr_t*, uint32_t)) "
- "rsaTypeGetNativeData; (void*) f((void*) 0x%lx, (void*) 0x%lx, data, 6); data[5]",
-
- // rsaElementGetNativeData(Context*, Element*, uint32_t* elemData,size)
- // Pack mType; mKind; mNormalized; mVectorSize; NumSubElements into elemData
- "uint32_t data[5]; void* (*f)(void*, void*, uint32_t*, uint32_t) = (void* (*)(void*, void*, uint32_t*, uint32_t)) "
- "rsaElementGetNativeData; (void*) f((void*) 0x%lx, (void*) 0x%lx, data, 5); data[0]", // Type
- "uint32_t data[5]; void* (*f)(void*, void*, uint32_t*, uint32_t) = (void* (*)(void*, void*, uint32_t*, uint32_t)) "
- "rsaElementGetNativeData; (void*) f((void*) 0x%lx, (void*) 0x%lx, data, 5); data[1]", // Kind
- "uint32_t data[5]; void* (*f)(void*, void*, uint32_t*, uint32_t) = (void* (*)(void*, void*, uint32_t*, uint32_t)) "
- "rsaElementGetNativeData; (void*) f((void*) 0x%lx, (void*) 0x%lx, data, 5); data[3]", // Vector size
- "uint32_t data[5]; void* (*f)(void*, void*, uint32_t*, uint32_t) = (void* (*)(void*, void*, uint32_t*, uint32_t)) "
- "rsaElementGetNativeData; (void*) f((void*) 0x%lx, (void*) 0x%lx, data, 5); data[4]", // Field count
-
- // rsaElementGetSubElements(RsContext con, RsElement elem, uintptr_t *ids, const char **names,
- // size_t *arraySizes, uint32_t dataSize)
- // Needed for Allocations of structs to gather details about fields/Subelements
- "void* ids[%u]; const char* names[%u]; size_t arr_size[%u];"
- "void* (*f) (void*, void*, uintptr_t*, const char**, size_t*, uint32_t) = "
- "(void* (*) (void*, void*, uintptr_t*, const char**, size_t*, uint32_t)) rsaElementGetSubElements;"
- "(void*) f((void*) 0x%lx, (void*) 0x%lx, (uintptr_t*) ids, names, arr_size, (uint32_t) %u);"
- "ids[%u]", // Element* of field
- "void* ids[%u]; const char* names[%u]; size_t arr_size[%u];"
- "void* (*f) (void*, void*, uintptr_t*, const char**, size_t*, uint32_t) = "
- "(void* (*) (void*, void*, uintptr_t*, const char**, size_t*, uint32_t)) rsaElementGetSubElements;"
- "(void*) f((void*) 0x%lx, (void*) 0x%lx, (uintptr_t*) ids, names, arr_size, (uint32_t) %u);"
- "names[%u]", // Name of field
- "void* ids[%u]; const char* names[%u]; size_t arr_size[%u];"
- "void* (*f) (void*, void*, uintptr_t*, const char**, size_t*, uint32_t) = "
- "(void* (*) (void*, void*, uintptr_t*, const char**, size_t*, uint32_t)) rsaElementGetSubElements;"
- "(void*) f((void*) 0x%lx, (void*) 0x%lx, (uintptr_t*) ids, names, arr_size, (uint32_t) %u);"
- "arr_size[%u]" // Array size of field
- };
-
-} // end of the anonymous namespace
-
-
-// Retrieve the string to JIT for the given expression
-const char*
-RenderScriptRuntime::JITTemplate(ExpressionStrings e)
-{
- // be nice to your Mips friend when adding new expression strings
- static_assert(sizeof(runtimeExpressions)/sizeof(runtimeExpressions[0]) ==
- sizeof(runtimeExpressions_mips)/sizeof(runtimeExpressions_mips[0]),
- "#runtimeExpressions != #runtimeExpressions_mips");
-
- assert((e >= eExprGetOffsetPtr && e <= eExprSubelementsArrSize) &&
- "Expression string out of bounds");
-
- llvm::Triple::ArchType arch = GetTargetRef().GetArchitecture().GetMachine();
-
- // mips JAL workaround
- if(arch == llvm::Triple::ArchType::mips64el || arch == llvm::Triple::ArchType::mipsel)
- return runtimeExpressions_mips[e];
- else
- return runtimeExpressions[e];
+ "uint32_t data[5]; (void*)rsaElementGetNativeData(0x%" PRIx64 ", 0x%" PRIx64 ", data, 5); data[0]", // Type
+ "uint32_t data[5]; (void*)rsaElementGetNativeData(0x%" PRIx64 ", 0x%" PRIx64 ", data, 5); data[1]", // Kind
+ "uint32_t data[5]; (void*)rsaElementGetNativeData(0x%" PRIx64 ", 0x%" PRIx64 ", data, 5); data[3]", // Vector Size
+ "uint32_t data[5]; (void*)rsaElementGetNativeData(0x%" PRIx64 ", 0x%" PRIx64 ", data, 5); data[4]", // Field Count
+
+ // rsaElementGetSubElements(RsContext con, RsElement elem, uintptr_t *ids, const char **names,
+ // size_t *arraySizes, uint32_t dataSize)
+ // Needed for Allocations of structs to gather details about fields/Subelements
+ // Element* of field
+ "void* ids[%" PRIu32 "]; const char* names[%" PRIu32 "]; size_t arr_size[%" PRIu32 "];"
+ "(void*)rsaElementGetSubElements(0x%" PRIx64 ", 0x%" PRIx64 ", ids, names, arr_size, %" PRIu32 "); ids[%" PRIu32 "]",
+
+ // Name of field
+ "void* ids[%" PRIu32 "]; const char* names[%" PRIu32 "]; size_t arr_size[%" PRIu32 "];"
+ "(void*)rsaElementGetSubElements(0x%" PRIx64 ", 0x%" PRIx64 ", ids, names, arr_size, %" PRIu32 "); names[%" PRIu32 "]",
+
+ // Array size of field
+ "void* ids[%" PRIu32 "]; const char* names[%" PRIu32 "]; size_t arr_size[%" PRIu32 "];"
+ "(void*)rsaElementGetSubElements(0x%" PRIx64 ", 0x%" PRIx64 ", ids, names, arr_size, %" PRIu32 "); arr_size[%" PRIu32 "]"
+ }};
+
+ return runtimeExpressions[e];
}
+} // end of the anonymous namespace
// JITs the RS runtime for the internal data pointer of an allocation.
@@ -1413,32 +1597,32 @@ RenderScriptRuntime::JITTemplate(ExpressionStrings e)
// Then sets the data_ptr member in Allocation with the result.
// Returns true on success, false otherwise
bool
-RenderScriptRuntime::JITDataPointer(AllocationDetails* allocation, StackFrame* frame_ptr,
- unsigned int x, unsigned int y, unsigned int z)
+RenderScriptRuntime::JITDataPointer(AllocationDetails *allocation, StackFrame *frame_ptr, uint32_t x,
+ uint32_t y, uint32_t z)
{
- Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
if (!allocation->address.isValid())
{
if (log)
- log->Printf("RenderScriptRuntime::JITDataPointer - Failed to find allocation details");
+ log->Printf("%s - failed to find allocation details.", __FUNCTION__);
return false;
}
- const char* expr_cstr = JITTemplate(eExprGetOffsetPtr);
+ const char *expr_cstr = JITTemplate(eExprGetOffsetPtr);
char buffer[jit_max_expr_size];
int chars_written = snprintf(buffer, jit_max_expr_size, expr_cstr, *allocation->address.get(), x, y, z);
if (chars_written < 0)
{
if (log)
- log->Printf("RenderScriptRuntime::JITDataPointer - Encoding error in snprintf()");
+ log->Printf("%s - encoding error in snprintf().", __FUNCTION__);
return false;
}
else if (chars_written >= jit_max_expr_size)
{
if (log)
- log->Printf("RenderScriptRuntime::JITDataPointer - Expression too long");
+ log->Printf("%s - expression too long.", __FUNCTION__);
return false;
}
@@ -1456,31 +1640,32 @@ RenderScriptRuntime::JITDataPointer(AllocationDetails* allocation, StackFrame* f
// Then sets the type_ptr member in Allocation with the result.
// Returns true on success, false otherwise
bool
-RenderScriptRuntime::JITTypePointer(AllocationDetails* allocation, StackFrame* frame_ptr)
+RenderScriptRuntime::JITTypePointer(AllocationDetails *allocation, StackFrame *frame_ptr)
{
- Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
if (!allocation->address.isValid() || !allocation->context.isValid())
{
if (log)
- log->Printf("RenderScriptRuntime::JITTypePointer - Failed to find allocation details");
+ log->Printf("%s - failed to find allocation details.", __FUNCTION__);
return false;
}
- const char* expr_cstr = JITTemplate(eExprAllocGetType);
+ const char *expr_cstr = JITTemplate(eExprAllocGetType);
char buffer[jit_max_expr_size];
- int chars_written = snprintf(buffer, jit_max_expr_size, expr_cstr, *allocation->context.get(), *allocation->address.get());
+ int chars_written =
+ snprintf(buffer, jit_max_expr_size, expr_cstr, *allocation->context.get(), *allocation->address.get());
if (chars_written < 0)
{
if (log)
- log->Printf("RenderScriptRuntime::JITDataPointer - Encoding error in snprintf()");
+ log->Printf("%s - encoding error in snprintf().", __FUNCTION__);
return false;
}
else if (chars_written >= jit_max_expr_size)
{
if (log)
- log->Printf("RenderScriptRuntime::JITTypePointer - Expression too long");
+ log->Printf("%s - expression too long.", __FUNCTION__);
return false;
}
@@ -1498,43 +1683,43 @@ RenderScriptRuntime::JITTypePointer(AllocationDetails* allocation, StackFrame* f
// Then sets dimension and element_ptr members in Allocation with the result.
// Returns true on success, false otherwise
bool
-RenderScriptRuntime::JITTypePacked(AllocationDetails* allocation, StackFrame* frame_ptr)
+RenderScriptRuntime::JITTypePacked(AllocationDetails *allocation, StackFrame *frame_ptr)
{
- Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
if (!allocation->type_ptr.isValid() || !allocation->context.isValid())
{
if (log)
- log->Printf("RenderScriptRuntime::JITTypePacked - Failed to find allocation details");
+ log->Printf("%s - Failed to find allocation details.", __FUNCTION__);
return false;
}
// Expression is different depending on if device is 32 or 64 bit
uint32_t archByteSize = GetProcess()->GetTarget().GetArchitecture().GetAddressByteSize();
- const unsigned int bits = archByteSize == 4 ? 32 : 64;
+ const uint32_t bits = archByteSize == 4 ? 32 : 64;
// We want 4 elements from packed data
- const unsigned int num_exprs = 4;
+ const uint32_t num_exprs = 4;
assert(num_exprs == (eExprTypeElemPtr - eExprTypeDimX + 1) && "Invalid number of expressions");
char buffer[num_exprs][jit_max_expr_size];
uint64_t results[num_exprs];
- for (unsigned int i = 0; i < num_exprs; ++i)
+ for (uint32_t i = 0; i < num_exprs; ++i)
{
- const char* expr_cstr = JITTemplate((ExpressionStrings) (eExprTypeDimX + i));
- int chars_written = snprintf(buffer[i], jit_max_expr_size, expr_cstr, bits,
- *allocation->context.get(), *allocation->type_ptr.get());
+ const char *expr_cstr = JITTemplate(ExpressionStrings(eExprTypeDimX + i));
+ int chars_written = snprintf(buffer[i], jit_max_expr_size, expr_cstr, bits, *allocation->context.get(),
+ *allocation->type_ptr.get());
if (chars_written < 0)
{
if (log)
- log->Printf("RenderScriptRuntime::JITDataPointer - Encoding error in snprintf()");
+ log->Printf("%s - encoding error in snprintf().", __FUNCTION__);
return false;
}
else if (chars_written >= jit_max_expr_size)
{
if (log)
- log->Printf("RenderScriptRuntime::JITTypePacked - Expression too long");
+ log->Printf("%s - expression too long.", __FUNCTION__);
return false;
}
@@ -1554,7 +1739,7 @@ RenderScriptRuntime::JITTypePacked(AllocationDetails* allocation, StackFrame* fr
allocation->element.element_ptr = elem_ptr;
if (log)
- log->Printf("RenderScriptRuntime::JITTypePacked - dims (%u, %u, %u) Element*: 0x%" PRIx64,
+ log->Printf("%s - dims (%" PRIu32 ", %" PRIu32 ", %" PRIu32 ") Element*: 0x%" PRIx64 ".", __FUNCTION__,
dims.dim_1, dims.dim_2, dims.dim_3, elem_ptr);
return true;
@@ -1564,38 +1749,38 @@ RenderScriptRuntime::JITTypePacked(AllocationDetails* allocation, StackFrame* fr
// Then sets type, type_vec_size, field_count and type_kind members in Element with the result.
// Returns true on success, false otherwise
bool
-RenderScriptRuntime::JITElementPacked(Element& elem, const lldb::addr_t context, StackFrame* frame_ptr)
+RenderScriptRuntime::JITElementPacked(Element &elem, const lldb::addr_t context, StackFrame *frame_ptr)
{
- Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
if (!elem.element_ptr.isValid())
{
if (log)
- log->Printf("RenderScriptRuntime::JITElementPacked - Failed to find allocation details");
+ log->Printf("%s - failed to find allocation details.", __FUNCTION__);
return false;
}
// We want 4 elements from packed data
- const unsigned int num_exprs = 4;
+ const uint32_t num_exprs = 4;
assert(num_exprs == (eExprElementFieldCount - eExprElementType + 1) && "Invalid number of expressions");
char buffer[num_exprs][jit_max_expr_size];
uint64_t results[num_exprs];
- for (unsigned int i = 0; i < num_exprs; i++)
+ for (uint32_t i = 0; i < num_exprs; i++)
{
- const char* expr_cstr = JITTemplate((ExpressionStrings) (eExprElementType + i));
+ const char *expr_cstr = JITTemplate(ExpressionStrings(eExprElementType + i));
int chars_written = snprintf(buffer[i], jit_max_expr_size, expr_cstr, context, *elem.element_ptr.get());
if (chars_written < 0)
{
if (log)
- log->Printf("RenderScriptRuntime::JITElementPacked - Encoding error in snprintf()");
+ log->Printf("%s - encoding error in snprintf().", __FUNCTION__);
return false;
}
else if (chars_written >= jit_max_expr_size)
{
if (log)
- log->Printf("RenderScriptRuntime::JITElementPacked - Expression too long");
+ log->Printf("%s - expression too long.", __FUNCTION__);
return false;
}
@@ -1611,8 +1796,8 @@ RenderScriptRuntime::JITElementPacked(Element& elem, const lldb::addr_t context,
elem.field_count = static_cast<uint32_t>(results[3]);
if (log)
- log->Printf("RenderScriptRuntime::JITElementPacked - data type %u, pixel type %u, vector size %u, field count %u",
- *elem.type.get(), *elem.type_kind.get(), *elem.type_vec_size.get(), *elem.field_count.get());
+ log->Printf("%s - data type %" PRIu32 ", pixel type %" PRIu32 ", vector size %" PRIu32 ", field count %" PRIu32,
+ __FUNCTION__, *elem.type.get(), *elem.type_kind.get(), *elem.type_vec_size.get(), *elem.field_count.get());
// If this Element has subelements then JIT rsaElementGetSubElements() for details about its fields
if (*elem.field_count.get() > 0 && !JITSubelements(elem, context, frame_ptr))
@@ -1625,14 +1810,14 @@ RenderScriptRuntime::JITElementPacked(Element& elem, const lldb::addr_t context,
// This is necessary for infering the struct type so we can pretty print the allocation's contents.
// Returns true on success, false otherwise
bool
-RenderScriptRuntime::JITSubelements(Element& elem, const lldb::addr_t context, StackFrame* frame_ptr)
+RenderScriptRuntime::JITSubelements(Element &elem, const lldb::addr_t context, StackFrame *frame_ptr)
{
- Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
if (!elem.element_ptr.isValid() || !elem.field_count.isValid())
{
if (log)
- log->Printf("RenderScriptRuntime::JITSubelements - Failed to find allocation details");
+ log->Printf("%s - failed to find allocation details.", __FUNCTION__);
return false;
}
@@ -1644,25 +1829,25 @@ RenderScriptRuntime::JITSubelements(Element& elem, const lldb::addr_t context, S
// Iterate over struct fields.
const uint32_t field_count = *elem.field_count.get();
- for (unsigned int field_index = 0; field_index < field_count; ++field_index)
+ for (uint32_t field_index = 0; field_index < field_count; ++field_index)
{
Element child;
- for (unsigned int expr_index = 0; expr_index < num_exprs; ++expr_index)
+ for (uint32_t expr_index = 0; expr_index < num_exprs; ++expr_index)
{
- const char* expr_cstr = JITTemplate((ExpressionStrings) (eExprSubelementsId + expr_index));
+ const char *expr_cstr = JITTemplate(ExpressionStrings(eExprSubelementsId + expr_index));
int chars_written = snprintf(expr_buffer, jit_max_expr_size, expr_cstr,
field_count, field_count, field_count,
context, *elem.element_ptr.get(), field_count, field_index);
if (chars_written < 0)
{
if (log)
- log->Printf("RenderScriptRuntime::JITSubelements - Encoding error in snprintf()");
+ log->Printf("%s - encoding error in snprintf().", __FUNCTION__);
return false;
}
else if (chars_written >= jit_max_expr_size)
{
if (log)
- log->Printf("RenderScriptRuntime::JITSubelements - Expression too long");
+ log->Printf("%s - expression too long.", __FUNCTION__);
return false;
}
@@ -1671,9 +1856,9 @@ RenderScriptRuntime::JITSubelements(Element& elem, const lldb::addr_t context, S
return false;
if (log)
- log->Printf("RenderScriptRuntime::JITSubelements - Expr result 0x%" PRIx64, results);
+ log->Printf("%s - expr result 0x%" PRIx64 ".", __FUNCTION__, results);
- switch(expr_index)
+ switch (expr_index)
{
case 0: // Element* of child
child.element_ptr = static_cast<addr_t>(results);
@@ -1689,7 +1874,7 @@ RenderScriptRuntime::JITSubelements(Element& elem, const lldb::addr_t context, S
else
{
if (log)
- log->Printf("RenderScriptRuntime::JITSubelements - Warning: Couldn't read field name");
+ log->Printf("%s - warning: Couldn't read field name.", __FUNCTION__);
}
break;
}
@@ -1718,22 +1903,22 @@ RenderScriptRuntime::JITSubelements(Element& elem, const lldb::addr_t context, S
// Using this offset minus the starting address we can calculate the size of the allocation.
// Returns true on success, false otherwise
bool
-RenderScriptRuntime::JITAllocationSize(AllocationDetails* allocation, StackFrame* frame_ptr)
+RenderScriptRuntime::JITAllocationSize(AllocationDetails *allocation, StackFrame *frame_ptr)
{
- Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
- if (!allocation->address.isValid() || !allocation->dimension.isValid()
- || !allocation->data_ptr.isValid() || !allocation->element.datum_size.isValid())
+ if (!allocation->address.isValid() || !allocation->dimension.isValid() || !allocation->data_ptr.isValid() ||
+ !allocation->element.datum_size.isValid())
{
if (log)
- log->Printf("RenderScriptRuntime::JITAllocationSize - Failed to find allocation details");
+ log->Printf("%s - failed to find allocation details.", __FUNCTION__);
return false;
}
// Find dimensions
- unsigned int dim_x = allocation->dimension.get()->dim_1;
- unsigned int dim_y = allocation->dimension.get()->dim_2;
- unsigned int dim_z = allocation->dimension.get()->dim_3;
+ uint32_t dim_x = allocation->dimension.get()->dim_1;
+ uint32_t dim_y = allocation->dimension.get()->dim_2;
+ uint32_t dim_z = allocation->dimension.get()->dim_3;
// Our plan of jitting the last element address doesn't seem to work for struct Allocations
// Instead try to infer the size ourselves without any inter element padding.
@@ -1746,12 +1931,12 @@ RenderScriptRuntime::JITAllocationSize(AllocationDetails* allocation, StackFrame
allocation->size = dim_x * dim_y * dim_z * *allocation->element.datum_size.get();
if (log)
- log->Printf("RenderScriptRuntime::JITAllocationSize - Infered size of struct allocation %u", *allocation->size.get());
-
+ log->Printf("%s - infered size of struct allocation %" PRIu32 ".", __FUNCTION__,
+ *allocation->size.get());
return true;
}
- const char* expr_cstr = JITTemplate(eExprGetOffsetPtr);
+ const char *expr_cstr = JITTemplate(eExprGetOffsetPtr);
char buffer[jit_max_expr_size];
// Calculate last element
@@ -1759,18 +1944,17 @@ RenderScriptRuntime::JITAllocationSize(AllocationDetails* allocation, StackFrame
dim_y = dim_y == 0 ? 0 : dim_y - 1;
dim_z = dim_z == 0 ? 0 : dim_z - 1;
- int chars_written = snprintf(buffer, jit_max_expr_size, expr_cstr, *allocation->address.get(),
- dim_x, dim_y, dim_z);
+ int chars_written = snprintf(buffer, jit_max_expr_size, expr_cstr, *allocation->address.get(), dim_x, dim_y, dim_z);
if (chars_written < 0)
{
if (log)
- log->Printf("RenderScriptRuntime::JITAllocationSize - Encoding error in snprintf()");
+ log->Printf("%s - encoding error in snprintf().", __FUNCTION__);
return false;
}
else if (chars_written >= jit_max_expr_size)
{
if (log)
- log->Printf("RenderScriptRuntime::JITAllocationSize - Expression too long");
+ log->Printf("%s - expression too long.", __FUNCTION__);
return false;
}
@@ -1780,7 +1964,8 @@ RenderScriptRuntime::JITAllocationSize(AllocationDetails* allocation, StackFrame
addr_t mem_ptr = static_cast<lldb::addr_t>(result);
// Find pointer to last element and add on size of an element
- allocation->size = static_cast<uint32_t>(mem_ptr - *allocation->data_ptr.get()) + *allocation->element.datum_size.get();
+ allocation->size =
+ static_cast<uint32_t>(mem_ptr - *allocation->data_ptr.get()) + *allocation->element.datum_size.get();
return true;
}
@@ -1789,32 +1974,31 @@ RenderScriptRuntime::JITAllocationSize(AllocationDetails* allocation, StackFrame
// This is done to detect padding, since allocated memory is 16-byte aligned.
// Returns true on success, false otherwise
bool
-RenderScriptRuntime::JITAllocationStride(AllocationDetails* allocation, StackFrame* frame_ptr)
+RenderScriptRuntime::JITAllocationStride(AllocationDetails *allocation, StackFrame *frame_ptr)
{
- Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
if (!allocation->address.isValid() || !allocation->data_ptr.isValid())
{
if (log)
- log->Printf("RenderScriptRuntime::JITAllocationStride - Failed to find allocation details");
+ log->Printf("%s - failed to find allocation details.", __FUNCTION__);
return false;
}
- const char* expr_cstr = JITTemplate(eExprGetOffsetPtr);
+ const char *expr_cstr = JITTemplate(eExprGetOffsetPtr);
char buffer[jit_max_expr_size];
- int chars_written = snprintf(buffer, jit_max_expr_size, expr_cstr, *allocation->address.get(),
- 0, 1, 0);
+ int chars_written = snprintf(buffer, jit_max_expr_size, expr_cstr, *allocation->address.get(), 0, 1, 0);
if (chars_written < 0)
{
if (log)
- log->Printf("RenderScriptRuntime::JITAllocationStride - Encoding error in snprintf()");
+ log->Printf("%s - encoding error in snprintf().", __FUNCTION__);
return false;
}
else if (chars_written >= jit_max_expr_size)
{
if (log)
- log->Printf("RenderScriptRuntime::JITAllocationStride - Expression too long");
+ log->Printf("%s - expression too long.", __FUNCTION__);
return false;
}
@@ -1830,7 +2014,7 @@ RenderScriptRuntime::JITAllocationStride(AllocationDetails* allocation, StackFra
// JIT all the current runtime info regarding an allocation
bool
-RenderScriptRuntime::RefreshAllocation(AllocationDetails* allocation, StackFrame* frame_ptr)
+RenderScriptRuntime::RefreshAllocation(AllocationDetails *allocation, StackFrame *frame_ptr)
{
// GetOffsetPointer()
if (!JITDataPointer(allocation, frame_ptr))
@@ -1862,9 +2046,9 @@ RenderScriptRuntime::RefreshAllocation(AllocationDetails* allocation, StackFrame
// This string should be the name of the struct type the Element represents.
// We need this string for pretty printing the Element to users.
void
-RenderScriptRuntime::FindStructTypeName(Element& elem, StackFrame* frame_ptr)
+RenderScriptRuntime::FindStructTypeName(Element &elem, StackFrame *frame_ptr)
{
- Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
if (!elem.type_name.IsEmpty()) // Name already set
return;
@@ -1883,7 +2067,7 @@ RenderScriptRuntime::FindStructTypeName(Element& elem, StackFrame* frame_ptr)
{
const VariableSP var_sp(variable_list.GetVariableAtIndex(var_index));
if (!var_sp)
- continue;
+ continue;
ValueObjectSP valobj_sp = ValueObjectVariable::Create(frame_ptr, var_sp);
if (!valobj_sp)
@@ -1914,13 +2098,13 @@ RenderScriptRuntime::FindStructTypeName(Element& elem, StackFrame* frame_ptr)
// RS can add extra struct members for padding in the format '#rs_padding_[0-9]+'
if (found && num_children < elem.children.size())
{
- const unsigned int size_diff = elem.children.size() - num_children;
+ const uint32_t size_diff = elem.children.size() - num_children;
if (log)
- log->Printf("RenderScriptRuntime::FindStructTypeName - %u padding struct entries", size_diff);
+ log->Printf("%s - %" PRIu32 " padding struct entries", __FUNCTION__, size_diff);
- for (unsigned int padding_index = 0; padding_index < size_diff; ++padding_index)
+ for (uint32_t padding_index = 0; padding_index < size_diff; ++padding_index)
{
- const ConstString& name = elem.children[num_children + padding_index].type_name;
+ const ConstString &name = elem.children[num_children + padding_index].type_name;
if (strcmp(name.AsCString(), "#rs_padding") < 0)
found = false;
}
@@ -1941,7 +2125,7 @@ RenderScriptRuntime::FindStructTypeName(Element& elem, StackFrame* frame_ptr)
// Save name of variable in Element.
elem.type_name = valobj_sp->GetTypeName();
if (log)
- log->Printf("RenderScriptRuntime::FindStructTypeName - Element name set to %s", elem.type_name.AsCString());
+ log->Printf("%s - element name set to %s", __FUNCTION__, elem.type_name.AsCString());
return;
}
@@ -1951,29 +2135,30 @@ RenderScriptRuntime::FindStructTypeName(Element& elem, StackFrame* frame_ptr)
// Function sets the datum_size member of Element. Representing the size of a single instance including padding.
// Assumes the relevant allocation information has already been jitted.
void
-RenderScriptRuntime::SetElementSize(Element& elem)
+RenderScriptRuntime::SetElementSize(Element &elem)
{
- Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
const Element::DataType type = *elem.type.get();
- assert(type >= Element::RS_TYPE_NONE && type <= Element::RS_TYPE_FONT
- && "Invalid allocation type");
+ assert(type >= Element::RS_TYPE_NONE && type <= Element::RS_TYPE_FONT && "Invalid allocation type");
- const unsigned int vec_size = *elem.type_vec_size.get();
- unsigned int data_size = 0;
- unsigned int padding = 0;
+ const uint32_t vec_size = *elem.type_vec_size.get();
+ uint32_t data_size = 0;
+ uint32_t padding = 0;
// Element is of a struct type, calculate size recursively.
if ((type == Element::RS_TYPE_NONE) && (elem.children.size() > 0))
{
- for (Element& child : elem.children)
+ for (Element &child : elem.children)
{
SetElementSize(child);
- const unsigned int array_size = child.array_size.isValid() ? *child.array_size.get() : 1;
+ const uint32_t array_size = child.array_size.isValid() ? *child.array_size.get() : 1;
data_size += *child.datum_size.get() * array_size;
}
}
- else if (type == Element::RS_TYPE_UNSIGNED_5_6_5 || type == Element::RS_TYPE_UNSIGNED_5_5_5_1 ||
- type == Element::RS_TYPE_UNSIGNED_4_4_4_4) // These have been packed already
+ // These have been packed already
+ else if (type == Element::RS_TYPE_UNSIGNED_5_6_5 ||
+ type == Element::RS_TYPE_UNSIGNED_5_5_5_1 ||
+ type == Element::RS_TYPE_UNSIGNED_4_4_4_4)
{
data_size = AllocationDetails::RSTypeToFormat[type][eElementSize];
}
@@ -1989,40 +2174,41 @@ RenderScriptRuntime::SetElementSize(Element& elem)
elem.padding = padding;
elem.datum_size = data_size + padding;
if (log)
- log->Printf("RenderScriptRuntime::SetElementSize - element size set to %u", data_size + padding);
+ log->Printf("%s - element size set to %" PRIu32, __FUNCTION__, data_size + padding);
}
// Given an allocation, this function copies the allocation contents from device into a buffer on the heap.
// Returning a shared pointer to the buffer containing the data.
std::shared_ptr<uint8_t>
-RenderScriptRuntime::GetAllocationData(AllocationDetails* allocation, StackFrame* frame_ptr)
+RenderScriptRuntime::GetAllocationData(AllocationDetails *allocation, StackFrame *frame_ptr)
{
- Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
// JIT all the allocation details
if (allocation->shouldRefresh())
{
if (log)
- log->Printf("RenderScriptRuntime::GetAllocationData - Allocation details not calculated yet, jitting info");
+ log->Printf("%s - allocation details not calculated yet, jitting info", __FUNCTION__);
if (!RefreshAllocation(allocation, frame_ptr))
{
if (log)
- log->Printf("RenderScriptRuntime::GetAllocationData - Couldn't JIT allocation details");
+ log->Printf("%s - couldn't JIT allocation details", __FUNCTION__);
return nullptr;
}
}
- assert(allocation->data_ptr.isValid() && allocation->element.type.isValid() && allocation->element.type_vec_size.isValid()
- && allocation->size.isValid() && "Allocation information not available");
+ assert(allocation->data_ptr.isValid() && allocation->element.type.isValid() &&
+ allocation->element.type_vec_size.isValid() && allocation->size.isValid() &&
+ "Allocation information not available");
// Allocate a buffer to copy data into
- const unsigned int size = *allocation->size.get();
+ const uint32_t size = *allocation->size.get();
std::shared_ptr<uint8_t> buffer(new uint8_t[size]);
if (!buffer)
{
if (log)
- log->Printf("RenderScriptRuntime::GetAllocationData - Couldn't allocate a %u byte buffer", size);
+ log->Printf("%s - couldn't allocate a %" PRIu32 " byte buffer", __FUNCTION__, size);
return nullptr;
}
@@ -2033,8 +2219,8 @@ RenderScriptRuntime::GetAllocationData(AllocationDetails* allocation, StackFrame
if (error.Fail())
{
if (log)
- log->Printf("RenderScriptRuntime::GetAllocationData - '%s' Couldn't read %u bytes of allocation data from 0x%" PRIx64,
- error.AsCString(), size, data_ptr);
+ log->Printf("%s - '%s' Couldn't read %" PRIu32 " bytes of allocation data from 0x%" PRIx64,
+ __FUNCTION__, error.AsCString(), size, data_ptr);
return nullptr;
}
@@ -2045,34 +2231,34 @@ RenderScriptRuntime::GetAllocationData(AllocationDetails* allocation, StackFrame
// There is a header at the start of the file, FileHeader, before the data content itself.
// Information from this header is used to display warnings to the user about incompatabilities
bool
-RenderScriptRuntime::LoadAllocation(Stream &strm, const uint32_t alloc_id, const char* filename, StackFrame* frame_ptr)
+RenderScriptRuntime::LoadAllocation(Stream &strm, const uint32_t alloc_id, const char *filename, StackFrame *frame_ptr)
{
- Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
// Find allocation with the given id
- AllocationDetails* alloc = FindAllocByID(strm, alloc_id);
+ AllocationDetails *alloc = FindAllocByID(strm, alloc_id);
if (!alloc)
return false;
if (log)
- log->Printf("RenderScriptRuntime::LoadAllocation - Found allocation 0x%" PRIx64, *alloc->address.get());
+ log->Printf("%s - found allocation 0x%" PRIx64, __FUNCTION__, *alloc->address.get());
// JIT all the allocation details
if (alloc->shouldRefresh())
{
if (log)
- log->Printf("RenderScriptRuntime::LoadAllocation - Allocation details not calculated yet, jitting info");
+ log->Printf("%s - allocation details not calculated yet, jitting info.", __FUNCTION__);
if (!RefreshAllocation(alloc, frame_ptr))
{
if (log)
- log->Printf("RenderScriptRuntime::LoadAllocation - Couldn't JIT allocation details");
+ log->Printf("%s - couldn't JIT allocation details", __FUNCTION__);
return false;
}
}
- assert(alloc->data_ptr.isValid() && alloc->element.type.isValid() && alloc->element.type_vec_size.isValid()
- && alloc->size.isValid() && alloc->element.datum_size.isValid() && "Allocation information not available");
+ assert(alloc->data_ptr.isValid() && alloc->element.type.isValid() && alloc->element.type_vec_size.isValid() &&
+ alloc->size.isValid() && alloc->element.datum_size.isValid() && "Allocation information not available");
// Check we can read from file
FileSpec file(filename, true);
@@ -2094,19 +2280,18 @@ RenderScriptRuntime::LoadAllocation(Stream &strm, const uint32_t alloc_id, const
DataBufferSP data_sp(file.ReadFileContents());
// Cast start of buffer to FileHeader and use pointer to read metadata
- void* file_buffer = data_sp->GetBytes();
- if (file_buffer == NULL || data_sp->GetByteSize() <
- (sizeof(AllocationDetails::FileHeader) + sizeof(AllocationDetails::ElementHeader)))
+ void *file_buffer = data_sp->GetBytes();
+ if (file_buffer == nullptr ||
+ data_sp->GetByteSize() < (sizeof(AllocationDetails::FileHeader) + sizeof(AllocationDetails::ElementHeader)))
{
strm.Printf("Error: File %s does not contain enough data for header", filename);
strm.EOL();
return false;
}
- const AllocationDetails::FileHeader* file_header = static_cast<AllocationDetails::FileHeader*>(file_buffer);
+ const AllocationDetails::FileHeader *file_header = static_cast<AllocationDetails::FileHeader *>(file_buffer);
// Check file starts with ascii characters "RSAD"
- if (file_header->ident[0] != 'R' || file_header->ident[1] != 'S' || file_header->ident[2] != 'A'
- || file_header->ident[3] != 'D')
+ if (memcmp(file_header->ident, "RSAD", 4))
{
strm.Printf("Error: File doesn't contain identifier for an RS allocation dump. Are you sure this is the correct file?");
strm.EOL();
@@ -2115,24 +2300,24 @@ RenderScriptRuntime::LoadAllocation(Stream &strm, const uint32_t alloc_id, const
// Look at the type of the root element in the header
AllocationDetails::ElementHeader root_element_header;
- memcpy(&root_element_header, static_cast<uint8_t*>(file_buffer) + sizeof(AllocationDetails::FileHeader),
+ memcpy(&root_element_header, static_cast<uint8_t *>(file_buffer) + sizeof(AllocationDetails::FileHeader),
sizeof(AllocationDetails::ElementHeader));
if (log)
- log->Printf("RenderScriptRuntime::LoadAllocation - header type %u, element size %u",
+ log->Printf("%s - header type %" PRIu32 ", element size %" PRIu32, __FUNCTION__,
root_element_header.type, root_element_header.element_size);
// Check if the target allocation and file both have the same number of bytes for an Element
if (*alloc->element.datum_size.get() != root_element_header.element_size)
{
- strm.Printf("Warning: Mismatched Element sizes - file %u bytes, allocation %u bytes",
+ strm.Printf("Warning: Mismatched Element sizes - file %" PRIu32 " bytes, allocation %" PRIu32 " bytes",
root_element_header.element_size, *alloc->element.datum_size.get());
strm.EOL();
}
// Check if the target allocation and file both have the same type
- const unsigned int alloc_type = static_cast<unsigned int>(*alloc->element.type.get());
- const unsigned int file_type = root_element_header.type;
+ const uint32_t alloc_type = static_cast<uint32_t>(*alloc->element.type.get());
+ const uint32_t file_type = root_element_header.type;
if (file_type > Element::RS_TYPE_FONT)
{
@@ -2142,36 +2327,36 @@ RenderScriptRuntime::LoadAllocation(Stream &strm, const uint32_t alloc_id, const
else if (alloc_type != file_type)
{
// Enum value isn't monotonous, so doesn't always index RsDataTypeToString array
- unsigned int printable_target_type_index = alloc_type;
- unsigned int printable_head_type_index = file_type;
+ uint32_t printable_target_type_index = alloc_type;
+ uint32_t printable_head_type_index = file_type;
if (alloc_type >= Element::RS_TYPE_ELEMENT && alloc_type <= Element::RS_TYPE_FONT)
- printable_target_type_index = static_cast<Element::DataType>(
- (alloc_type - Element::RS_TYPE_ELEMENT) + Element::RS_TYPE_MATRIX_2X2 + 1);
+ printable_target_type_index = static_cast<Element::DataType>((alloc_type - Element::RS_TYPE_ELEMENT) +
+ Element::RS_TYPE_MATRIX_2X2 + 1);
if (file_type >= Element::RS_TYPE_ELEMENT && file_type <= Element::RS_TYPE_FONT)
- printable_head_type_index = static_cast<Element::DataType>(
- (file_type - Element::RS_TYPE_ELEMENT) + Element::RS_TYPE_MATRIX_2X2 + 1);
+ printable_head_type_index = static_cast<Element::DataType>((file_type - Element::RS_TYPE_ELEMENT) +
+ Element::RS_TYPE_MATRIX_2X2 + 1);
- const char* file_type_cstr = AllocationDetails::RsDataTypeToString[printable_head_type_index][0];
- const char* target_type_cstr = AllocationDetails::RsDataTypeToString[printable_target_type_index][0];
+ const char *file_type_cstr = AllocationDetails::RsDataTypeToString[printable_head_type_index][0];
+ const char *target_type_cstr = AllocationDetails::RsDataTypeToString[printable_target_type_index][0];
- strm.Printf("Warning: Mismatched Types - file '%s' type, allocation '%s' type",
- file_type_cstr, target_type_cstr);
+ strm.Printf("Warning: Mismatched Types - file '%s' type, allocation '%s' type", file_type_cstr,
+ target_type_cstr);
strm.EOL();
}
// Advance buffer past header
- file_buffer = static_cast<uint8_t*>(file_buffer) + file_header->hdr_size;
+ file_buffer = static_cast<uint8_t *>(file_buffer) + file_header->hdr_size;
// Calculate size of allocation data in file
size_t length = data_sp->GetByteSize() - file_header->hdr_size;
// Check if the target allocation and file both have the same total data size.
- const unsigned int alloc_size = *alloc->size.get();
+ const uint32_t alloc_size = *alloc->size.get();
if (alloc_size != length)
{
- strm.Printf("Warning: Mismatched allocation sizes - file 0x%" PRIx64 " bytes, allocation 0x%x bytes",
- (uint64_t) length, alloc_size);
+ strm.Printf("Warning: Mismatched allocation sizes - file 0x%" PRIx64 " bytes, allocation 0x%" PRIx32 " bytes",
+ (uint64_t)length, alloc_size);
strm.EOL();
length = alloc_size < length ? alloc_size : length; // Set length to copy to minimum
}
@@ -2187,7 +2372,7 @@ RenderScriptRuntime::LoadAllocation(Stream &strm, const uint32_t alloc_id, const
return false;
}
- strm.Printf("Contents of file '%s' read into allocation %u", filename, alloc->id);
+ strm.Printf("Contents of file '%s' read into allocation %" PRIu32, filename, alloc->id);
strm.EOL();
return true;
@@ -2196,9 +2381,11 @@ RenderScriptRuntime::LoadAllocation(Stream &strm, const uint32_t alloc_id, const
// Function takes as parameters a byte buffer, which will eventually be written to file as the element header,
// an offset into that buffer, and an Element that will be saved into the buffer at the parametrised offset.
// Return value is the new offset after writing the element into the buffer.
-// Elements are saved to the file as the ElementHeader struct followed by offsets to the structs of all the element's children.
+// Elements are saved to the file as the ElementHeader struct followed by offsets to the structs of all the element's
+// children.
size_t
-RenderScriptRuntime::PopulateElementHeaders(const std::shared_ptr<uint8_t> header_buffer, size_t offset, const Element& elem)
+RenderScriptRuntime::PopulateElementHeaders(const std::shared_ptr<uint8_t> header_buffer, size_t offset,
+ const Element &elem)
{
// File struct for an element header with all the relevant details copied from elem.
// We assume members are valid already.
@@ -2211,13 +2398,13 @@ RenderScriptRuntime::PopulateElementHeaders(const std::shared_ptr<uint8_t> heade
const size_t elem_header_size = sizeof(AllocationDetails::ElementHeader);
// Copy struct into buffer and advance offset
- // We assume that header_buffer has been checked for NULL before this method is called
+ // We assume that header_buffer has been checked for nullptr before this method is called
memcpy(header_buffer.get() + offset, &elem_header, elem_header_size);
offset += elem_header_size;
// Starting offset of child ElementHeader struct
size_t child_offset = offset + ((elem.children.size() + 1) * sizeof(uint32_t));
- for (const RenderScriptRuntime::Element& child : elem.children)
+ for (const RenderScriptRuntime::Element &child : elem.children)
{
// Recursively populate the buffer with the element header structs of children.
// Then save the offsets where they were set after the parent element header.
@@ -2233,17 +2420,18 @@ RenderScriptRuntime::PopulateElementHeaders(const std::shared_ptr<uint8_t> heade
return child_offset;
}
-// Given an Element object this function returns the total size needed in the file header to store the element's details.
+// Given an Element object this function returns the total size needed in the file header to store the element's
+// details.
// Taking into account the size of the element header struct, plus the offsets to all the element's children.
// Function is recursive so that the size of all ancestors is taken into account.
size_t
-RenderScriptRuntime::CalculateElementHeaderSize(const Element& elem)
+RenderScriptRuntime::CalculateElementHeaderSize(const Element &elem)
{
size_t size = (elem.children.size() + 1) * sizeof(uint32_t); // Offsets to children plus zero terminator
- size += sizeof(AllocationDetails::ElementHeader); // Size of header struct with type details
+ size += sizeof(AllocationDetails::ElementHeader); // Size of header struct with type details
// Calculate recursively for all descendants
- for (const Element& child : elem.children)
+ for (const Element &child : elem.children)
size += CalculateElementHeaderSize(child);
return size;
@@ -2253,34 +2441,35 @@ RenderScriptRuntime::CalculateElementHeaderSize(const Element& elem)
// This file can then be loaded later into a different allocation.
// There is a header, FileHeader, before the allocation data containing meta-data.
bool
-RenderScriptRuntime::SaveAllocation(Stream &strm, const uint32_t alloc_id, const char* filename, StackFrame* frame_ptr)
+RenderScriptRuntime::SaveAllocation(Stream &strm, const uint32_t alloc_id, const char *filename, StackFrame *frame_ptr)
{
- Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
// Find allocation with the given id
- AllocationDetails* alloc = FindAllocByID(strm, alloc_id);
+ AllocationDetails *alloc = FindAllocByID(strm, alloc_id);
if (!alloc)
return false;
if (log)
- log->Printf("RenderScriptRuntime::SaveAllocation - Found allocation 0x%" PRIx64, *alloc->address.get());
+ log->Printf("%s - found allocation 0x%" PRIx64 ".", __FUNCTION__, *alloc->address.get());
- // JIT all the allocation details
+ // JIT all the allocation details
if (alloc->shouldRefresh())
{
if (log)
- log->Printf("RenderScriptRuntime::SaveAllocation - Allocation details not calculated yet, jitting info");
+ log->Printf("%s - allocation details not calculated yet, jitting info.", __FUNCTION__);
if (!RefreshAllocation(alloc, frame_ptr))
{
if (log)
- log->Printf("RenderScriptRuntime::SaveAllocation - Couldn't JIT allocation details");
+ log->Printf("%s - couldn't JIT allocation details.", __FUNCTION__);
return false;
}
}
- assert(alloc->data_ptr.isValid() && alloc->element.type.isValid() && alloc->element.type_vec_size.isValid() && alloc->element.datum_size.get()
- && alloc->element.type_kind.isValid() && alloc->dimension.isValid() && "Allocation information not available");
+ assert(alloc->data_ptr.isValid() && alloc->element.type.isValid() && alloc->element.type_vec_size.isValid() &&
+ alloc->element.datum_size.get() && alloc->element.type_kind.isValid() && alloc->dimension.isValid() &&
+ "Allocation information not available");
// Check we can create writable file
FileSpec file_spec(filename, true);
@@ -2303,7 +2492,7 @@ RenderScriptRuntime::SaveAllocation(Stream &strm, const uint32_t alloc_id, const
// Create the file header
AllocationDetails::FileHeader head;
- head.ident[0] = 'R'; head.ident[1] = 'S'; head.ident[2] = 'A'; head.ident[3] = 'D';
+ memcpy(head.ident, "RSAD", 4);
head.dims[0] = static_cast<uint32_t>(alloc->dimension.get()->dim_1);
head.dims[1] = static_cast<uint32_t>(alloc->dimension.get()->dim_2);
head.dims[2] = static_cast<uint32_t>(alloc->dimension.get()->dim_3);
@@ -2315,7 +2504,7 @@ RenderScriptRuntime::SaveAllocation(Stream &strm, const uint32_t alloc_id, const
// Write the file header
size_t num_bytes = sizeof(AllocationDetails::FileHeader);
if (log)
- log->Printf("RenderScriptRuntime::SaveAllocation - Writing File Header, 0x%zX bytes", num_bytes);
+ log->Printf("%s - writing File Header, 0x%" PRIx64 " bytes", __FUNCTION__, (uint64_t)num_bytes);
Error err = file.Write(&head, num_bytes);
if (!err.Success())
@@ -2329,7 +2518,7 @@ RenderScriptRuntime::SaveAllocation(Stream &strm, const uint32_t alloc_id, const
std::shared_ptr<uint8_t> element_header_buffer(new uint8_t[element_header_size]);
if (element_header_buffer == nullptr)
{
- strm.Printf("Internal Error: Couldn't allocate %zu bytes on the heap", element_header_size);
+ strm.Printf("Internal Error: Couldn't allocate %" PRIu64 " bytes on the heap", (uint64_t)element_header_size);
strm.EOL();
return false;
}
@@ -2339,7 +2528,7 @@ RenderScriptRuntime::SaveAllocation(Stream &strm, const uint32_t alloc_id, const
// Write headers for allocation element type to file
num_bytes = element_header_size;
if (log)
- log->Printf("RenderScriptRuntime::SaveAllocation - Writing Element Headers, 0x%zX bytes", num_bytes);
+ log->Printf("%s - writing element headers, 0x%" PRIx64 " bytes.", __FUNCTION__, (uint64_t)num_bytes);
err = file.Write(element_header_buffer.get(), num_bytes);
if (!err.Success())
@@ -2352,7 +2541,7 @@ RenderScriptRuntime::SaveAllocation(Stream &strm, const uint32_t alloc_id, const
// Write allocation data to file
num_bytes = static_cast<size_t>(*alloc->size.get());
if (log)
- log->Printf("RenderScriptRuntime::SaveAllocation - Writing 0x%zX bytes", num_bytes);
+ log->Printf("%s - writing 0x%" PRIx64 " bytes", __FUNCTION__, (uint64_t)num_bytes);
err = file.Write(buffer.get(), num_bytes);
if (!err.Success())
@@ -2370,7 +2559,7 @@ RenderScriptRuntime::SaveAllocation(Stream &strm, const uint32_t alloc_id, const
bool
RenderScriptRuntime::LoadModule(const lldb::ModuleSP &module_sp)
{
- Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
if (module_sp)
{
@@ -2424,7 +2613,8 @@ RenderScriptRuntime::LoadModule(const lldb::ModuleSP &module_sp)
{
m_libRS = module_sp;
static ConstString gDbgPresentStr("gDebuggerPresent");
- const Symbol* debug_present = m_libRS->FindFirstSymbolWithNameAndType(gDbgPresentStr, eSymbolTypeData);
+ const Symbol *debug_present =
+ m_libRS->FindFirstSymbolWithNameAndType(gDbgPresentStr, eSymbolTypeData);
if (debug_present)
{
Error error;
@@ -2432,21 +2622,22 @@ RenderScriptRuntime::LoadModule(const lldb::ModuleSP &module_sp)
Target &target = GetProcess()->GetTarget();
addr_t addr = debug_present->GetLoadAddress(&target);
GetProcess()->WriteMemory(addr, &flag, sizeof(flag), error);
- if(error.Success())
+ if (error.Success())
{
if (log)
- log->Printf ("RenderScriptRuntime::LoadModule - Debugger present flag set on debugee");
+ log->Printf("%s - debugger present flag set on debugee.", __FUNCTION__);
m_debuggerPresentFlagged = true;
}
else if (log)
{
- log->Printf ("RenderScriptRuntime::LoadModule - Error writing debugger present flags '%s' ", error.AsCString());
+ log->Printf("%s - error writing debugger present flags '%s' ", __FUNCTION__,
+ error.AsCString());
}
}
else if (log)
{
- log->Printf ("RenderScriptRuntime::LoadModule - Error writing debugger present flags - symbol not found");
+ log->Printf("%s - error writing debugger present flags - symbol not found", __FUNCTION__);
}
}
break;
@@ -2475,98 +2666,98 @@ RenderScriptRuntime::Update()
// The maximum line length of an .rs.info packet
#define MAXLINE 500
+#define STRINGIFY(x) #x
+#define MAXLINESTR_(x) "%" STRINGIFY(x) "s"
+#define MAXLINESTR MAXLINESTR_(MAXLINE)
// The .rs.info symbol in renderscript modules contains a string which needs to be parsed.
// The string is basic and is parsed on a line by line basis.
bool
RSModuleDescriptor::ParseRSInfo()
{
+ assert(m_module);
const Symbol *info_sym = m_module->FindFirstSymbolWithNameAndType(ConstString(".rs.info"), eSymbolTypeData);
- if (info_sym)
- {
- const addr_t addr = info_sym->GetAddressRef().GetFileAddress();
- const addr_t size = info_sym->GetByteSize();
- const FileSpec fs = m_module->GetFileSpec();
+ if (!info_sym)
+ return false;
- DataBufferSP buffer = fs.ReadFileContents(addr, size);
+ const addr_t addr = info_sym->GetAddressRef().GetFileAddress();
+ if (addr == LLDB_INVALID_ADDRESS)
+ return false;
- if (!buffer)
- return false;
+ const addr_t size = info_sym->GetByteSize();
+ const FileSpec fs = m_module->GetFileSpec();
- std::string info((const char *)buffer->GetBytes());
+ const DataBufferSP buffer = fs.ReadFileContents(addr, size);
+ if (!buffer)
+ return false;
- std::vector<std::string> info_lines;
- size_t lpos = info.find('\n');
- while (lpos != std::string::npos)
+ // split rs.info. contents into lines
+ std::vector<std::string> info_lines;
+ {
+ const std::string info((const char *)buffer->GetBytes());
+ for (size_t tail = 0; tail < info.size();)
{
- info_lines.push_back(info.substr(0, lpos));
- info = info.substr(lpos + 1);
- lpos = info.find('\n');
+ // find next new line or end of string
+ size_t head = info.find('\n', tail);
+ head = (head == std::string::npos) ? info.size() : head;
+ std::string line = info.substr(tail, head - tail);
+ // add to line list
+ info_lines.push_back(line);
+ tail = head + 1;
}
- size_t offset = 0;
- while (offset < info_lines.size())
+ }
+
+ std::array<char, MAXLINE> name{{'\0'}};
+ std::array<char, MAXLINE> value{{'\0'}};
+
+ // parse all text lines of .rs.info
+ for (auto line = info_lines.begin(); line != info_lines.end(); ++line)
+ {
+ uint32_t numDefns = 0;
+ if (sscanf(line->c_str(), "exportVarCount: %" PRIu32 "", &numDefns) == 1)
{
- std::string line = info_lines[offset];
- // Parse directives
- uint32_t numDefns = 0;
- if (sscanf(line.c_str(), "exportVarCount: %u", &numDefns) == 1)
- {
- while (numDefns--)
- m_globals.push_back(RSGlobalDescriptor(this, info_lines[++offset].c_str()));
- }
- else if (sscanf(line.c_str(), "exportFuncCount: %u", &numDefns) == 1)
- {
- }
- else if (sscanf(line.c_str(), "exportForEachCount: %u", &numDefns) == 1)
+ while (numDefns--)
+ m_globals.push_back(RSGlobalDescriptor(this, (++line)->c_str()));
+ }
+ else if (sscanf(line->c_str(), "exportForEachCount: %" PRIu32 "", &numDefns) == 1)
+ {
+ while (numDefns--)
{
- char name[MAXLINE];
- while (numDefns--)
+ uint32_t slot = 0;
+ name[0] = '\0';
+ static const char *fmt_s = "%" PRIu32 " - " MAXLINESTR;
+ if (sscanf((++line)->c_str(), fmt_s, &slot, name.data()) == 2)
{
- uint32_t slot = 0;
- name[0] = '\0';
- if (sscanf(info_lines[++offset].c_str(), "%u - %s", &slot, &name[0]) == 2)
- {
- m_kernels.push_back(RSKernelDescriptor(this, name, slot));
- }
+ if (name[0] != '\0')
+ m_kernels.push_back(RSKernelDescriptor(this, name.data(), slot));
}
}
- else if (sscanf(line.c_str(), "pragmaCount: %u", &numDefns) == 1)
+ }
+ else if (sscanf(line->c_str(), "pragmaCount: %" PRIu32 "", &numDefns) == 1)
+ {
+ while (numDefns--)
{
- char name[MAXLINE];
- char value[MAXLINE];
- while (numDefns--)
+ name[0] = value[0] = '\0';
+ static const char *fmt_s = MAXLINESTR " - " MAXLINESTR;
+ if (sscanf((++line)->c_str(), fmt_s, name.data(), value.data()) != 0)
{
- name[0] = '\0';
- value[0] = '\0';
- if (sscanf(info_lines[++offset].c_str(), "%s - %s", &name[0], &value[0]) != 0
- && (name[0] != '\0'))
- {
- m_pragmas[std::string(name)] = value;
- }
+ if (name[0] != '\0')
+ m_pragmas[std::string(name.data())] = value.data();
}
}
- else if (sscanf(line.c_str(), "objectSlotCount: %u", &numDefns) == 1)
+ }
+ else
+ {
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
+ if (log)
{
+ log->Printf("%s - skipping .rs.info field '%s'", __FUNCTION__, line->c_str());
}
-
- offset++;
}
- return m_kernels.size() > 0;
}
- return false;
-}
-bool
-RenderScriptRuntime::ProbeModules(const ModuleList module_list)
-{
- bool rs_found = false;
- size_t num_modules = module_list.GetSize();
- for (size_t i = 0; i < num_modules; i++)
- {
- auto module = module_list.GetModuleAtIndex(i);
- rs_found |= LoadModule(module);
- }
- return rs_found;
+ // 'root' kernel should always be present
+ return m_kernels.size() > 0;
}
void
@@ -2616,7 +2807,7 @@ RenderScriptRuntime::DumpContexts(Stream &strm) const
// Iterate over all of the currently discovered scripts.
// Note: We cant push or pop from m_scripts inside this loop or it may invalidate script.
- for (const auto & script : m_scripts)
+ for (const auto &script : m_scripts)
{
if (!script->context.isValid())
continue;
@@ -2632,7 +2823,7 @@ RenderScriptRuntime::DumpContexts(Stream &strm) const
}
}
- for (const auto& cRef : contextReferences)
+ for (const auto &cRef : contextReferences)
{
strm.Printf("Context 0x%" PRIx64 ": %" PRIu64 " script instances", cRef.first, cRef.second);
strm.EOL();
@@ -2648,7 +2839,7 @@ RenderScriptRuntime::DumpKernels(Stream &strm) const
strm.IndentMore();
for (const auto &module : m_rsmodules)
{
- strm.Printf("Resource '%s':",module->m_resname.c_str());
+ strm.Printf("Resource '%s':", module->m_resname.c_str());
strm.EOL();
for (const auto &kernel : module->m_kernels)
{
@@ -2659,32 +2850,31 @@ RenderScriptRuntime::DumpKernels(Stream &strm) const
strm.IndentLess();
}
-RenderScriptRuntime::AllocationDetails*
+RenderScriptRuntime::AllocationDetails *
RenderScriptRuntime::FindAllocByID(Stream &strm, const uint32_t alloc_id)
{
- AllocationDetails* alloc = nullptr;
+ AllocationDetails *alloc = nullptr;
// See if we can find allocation using id as an index;
- if (alloc_id <= m_allocations.size() && alloc_id != 0
- && m_allocations[alloc_id-1]->id == alloc_id)
+ if (alloc_id <= m_allocations.size() && alloc_id != 0 && m_allocations[alloc_id - 1]->id == alloc_id)
{
- alloc = m_allocations[alloc_id-1].get();
+ alloc = m_allocations[alloc_id - 1].get();
return alloc;
}
// Fallback to searching
- for (const auto & a : m_allocations)
+ for (const auto &a : m_allocations)
{
- if (a->id == alloc_id)
- {
- alloc = a.get();
- break;
- }
+ if (a->id == alloc_id)
+ {
+ alloc = a.get();
+ break;
+ }
}
if (alloc == nullptr)
{
- strm.Printf("Error: Couldn't find allocation with id matching %u", alloc_id);
+ strm.Printf("Error: Couldn't find allocation with id matching %" PRIu32, alloc_id);
strm.EOL();
}
@@ -2693,23 +2883,23 @@ RenderScriptRuntime::FindAllocByID(Stream &strm, const uint32_t alloc_id)
// Prints the contents of an allocation to the output stream, which may be a file
bool
-RenderScriptRuntime::DumpAllocation(Stream &strm, StackFrame* frame_ptr, const uint32_t id)
+RenderScriptRuntime::DumpAllocation(Stream &strm, StackFrame *frame_ptr, const uint32_t id)
{
- Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
// Check we can find the desired allocation
- AllocationDetails* alloc = FindAllocByID(strm, id);
+ AllocationDetails *alloc = FindAllocByID(strm, id);
if (!alloc)
return false; // FindAllocByID() will print error message for us here
if (log)
- log->Printf("RenderScriptRuntime::DumpAllocation - Found allocation 0x%" PRIx64, *alloc->address.get());
+ log->Printf("%s - found allocation 0x%" PRIx64, __FUNCTION__, *alloc->address.get());
// Check we have information about the allocation, if not calculate it
if (alloc->shouldRefresh())
{
if (log)
- log->Printf("RenderScriptRuntime::DumpAllocation - Allocation details not calculated yet, jitting info");
+ log->Printf("%s - allocation details not calculated yet, jitting info.", __FUNCTION__);
// JIT all the allocation information
if (!RefreshAllocation(alloc, frame_ptr))
@@ -2721,11 +2911,10 @@ RenderScriptRuntime::DumpAllocation(Stream &strm, StackFrame* frame_ptr, const u
}
// Establish format and size of each data element
- const unsigned int vec_size = *alloc->element.type_vec_size.get();
+ const uint32_t vec_size = *alloc->element.type_vec_size.get();
const Element::DataType type = *alloc->element.type.get();
- assert(type >= Element::RS_TYPE_NONE && type <= Element::RS_TYPE_FONT
- && "Invalid allocation type");
+ assert(type >= Element::RS_TYPE_NONE && type <= Element::RS_TYPE_FONT && "Invalid allocation type");
lldb::Format format;
if (type >= Element::RS_TYPE_ELEMENT)
@@ -2734,10 +2923,10 @@ RenderScriptRuntime::DumpAllocation(Stream &strm, StackFrame* frame_ptr, const u
format = vec_size == 1 ? static_cast<lldb::Format>(AllocationDetails::RSTypeToFormat[type][eFormatSingle])
: static_cast<lldb::Format>(AllocationDetails::RSTypeToFormat[type][eFormatVector]);
- const unsigned int data_size = *alloc->element.datum_size.get();
+ const uint32_t data_size = *alloc->element.datum_size.get();
if (log)
- log->Printf("RenderScriptRuntime::DumpAllocation - Element size %u bytes, including padding", data_size);
+ log->Printf("%s - element size %" PRIu32 " bytes, including padding", __FUNCTION__, data_size);
// Allocate a buffer to copy data into
std::shared_ptr<uint8_t> buffer = GetAllocationData(alloc, frame_ptr);
@@ -2761,44 +2950,45 @@ RenderScriptRuntime::DumpAllocation(Stream &strm, StackFrame* frame_ptr, const u
return false;
}
}
- const unsigned int stride = *alloc->stride.get();
- const unsigned int size = *alloc->size.get(); // Size of whole allocation
- const unsigned int padding = alloc->element.padding.isValid() ? *alloc->element.padding.get() : 0;
+ const uint32_t stride = *alloc->stride.get();
+ const uint32_t size = *alloc->size.get(); // Size of whole allocation
+ const uint32_t padding = alloc->element.padding.isValid() ? *alloc->element.padding.get() : 0;
if (log)
- log->Printf("RenderScriptRuntime::DumpAllocation - stride %u bytes, size %u bytes, padding %u", stride, size, padding);
+ log->Printf("%s - stride %" PRIu32 " bytes, size %" PRIu32 " bytes, padding %" PRIu32,
+ __FUNCTION__, stride, size, padding);
// Find dimensions used to index loops, so need to be non-zero
- unsigned int dim_x = alloc->dimension.get()->dim_1;
+ uint32_t dim_x = alloc->dimension.get()->dim_1;
dim_x = dim_x == 0 ? 1 : dim_x;
- unsigned int dim_y = alloc->dimension.get()->dim_2;
+ uint32_t dim_y = alloc->dimension.get()->dim_2;
dim_y = dim_y == 0 ? 1 : dim_y;
- unsigned int dim_z = alloc->dimension.get()->dim_3;
+ uint32_t dim_z = alloc->dimension.get()->dim_3;
dim_z = dim_z == 0 ? 1 : dim_z;
// Use data extractor to format output
const uint32_t archByteSize = GetProcess()->GetTarget().GetArchitecture().GetAddressByteSize();
DataExtractor alloc_data(buffer.get(), size, GetProcess()->GetByteOrder(), archByteSize);
- unsigned int offset = 0; // Offset in buffer to next element to be printed
- unsigned int prev_row = 0; // Offset to the start of the previous row
+ uint32_t offset = 0; // Offset in buffer to next element to be printed
+ uint32_t prev_row = 0; // Offset to the start of the previous row
// Iterate over allocation dimensions, printing results to user
strm.Printf("Data (X, Y, Z):");
- for (unsigned int z = 0; z < dim_z; ++z)
+ for (uint32_t z = 0; z < dim_z; ++z)
{
- for (unsigned int y = 0; y < dim_y; ++y)
+ for (uint32_t y = 0; y < dim_y; ++y)
{
// Use stride to index start of next row.
- if (!(y==0 && z==0))
+ if (!(y == 0 && z == 0))
offset = prev_row + stride;
prev_row = offset;
// Print each element in the row individually
- for (unsigned int x = 0; x < dim_x; ++x)
+ for (uint32_t x = 0; x < dim_x; ++x)
{
- strm.Printf("\n(%u, %u, %u) = ", x, y, z);
+ strm.Printf("\n(%" PRIu32 ", %" PRIu32 ", %" PRIu32 ") = ", x, y, z);
if ((type == Element::RS_TYPE_NONE) && (alloc->element.children.size() > 0) &&
(alloc->element.type_name != Element::GetFallbackStructName()))
{
@@ -2812,12 +3002,12 @@ RenderScriptRuntime::DumpAllocation(Stream &strm, StackFrame* frame_ptr, const u
// Setup expression as derefrencing a pointer cast to element address.
char expr_char_buffer[jit_max_expr_size];
int chars_written = snprintf(expr_char_buffer, jit_max_expr_size, "*(%s*) 0x%" PRIx64,
- alloc->element.type_name.AsCString(), *alloc->data_ptr.get() + offset);
+ alloc->element.type_name.AsCString(), *alloc->data_ptr.get() + offset);
if (chars_written < 0 || chars_written >= jit_max_expr_size)
{
if (log)
- log->Printf("RenderScriptRuntime::DumpAllocation- Error in snprintf()");
+ log->Printf("%s - error in snprintf().", __FUNCTION__);
continue;
}
@@ -2841,10 +3031,35 @@ RenderScriptRuntime::DumpAllocation(Stream &strm, StackFrame* frame_ptr, const u
return true;
}
-// Prints infomation regarding all the currently loaded allocations.
+// Function recalculates all our cached information about allocations by jitting the
+// RS runtime regarding each allocation we know about.
+// Returns true if all allocations could be recomputed, false otherwise.
+bool
+RenderScriptRuntime::RecomputeAllAllocations(Stream &strm, StackFrame *frame_ptr)
+{
+ bool success = true;
+ for (auto &alloc : m_allocations)
+ {
+ // JIT current allocation information
+ if (!RefreshAllocation(alloc.get(), frame_ptr))
+ {
+ strm.Printf("Error: Couldn't evaluate details for allocation %" PRIu32 "\n", alloc->id);
+ success = false;
+ }
+ }
+
+ if (success)
+ strm.Printf("All allocations successfully recomputed");
+ strm.EOL();
+
+ return success;
+}
+
+// Prints information regarding currently loaded allocations.
// These details are gathered by jitting the runtime, which has as latency.
+// Index parameter specifies a single allocation ID to print, or a zero value to print them all
void
-RenderScriptRuntime::ListAllocations(Stream &strm, StackFrame* frame_ptr, bool recompute)
+RenderScriptRuntime::ListAllocations(Stream &strm, StackFrame *frame_ptr, const uint32_t index)
{
strm.Printf("RenderScript Allocations:");
strm.EOL();
@@ -2852,17 +3067,20 @@ RenderScriptRuntime::ListAllocations(Stream &strm, StackFrame* frame_ptr, bool r
for (auto &alloc : m_allocations)
{
- // JIT the allocation info if we haven't done it, or the user forces us to.
- bool do_refresh = alloc->shouldRefresh() || recompute;
+ // index will only be zero if we want to print all allocations
+ if (index != 0 && index != alloc->id)
+ continue;
// JIT current allocation information
- if (do_refresh && !RefreshAllocation(alloc.get(), frame_ptr))
+ if (alloc->shouldRefresh() && !RefreshAllocation(alloc.get(), frame_ptr))
{
- strm.Printf("Error: Couldn't evaluate details for allocation %u\n", alloc->id);
+ strm.Printf("Error: Couldn't evaluate details for allocation %" PRIu32, alloc->id);
+ strm.EOL();
continue;
}
- strm.Printf("%u:\n",alloc->id);
+ strm.Printf("%" PRIu32 ":", alloc->id);
+ strm.EOL();
strm.IndentMore();
strm.Indent("Context: ");
@@ -2887,9 +3105,8 @@ RenderScriptRuntime::ListAllocations(Stream &strm, StackFrame* frame_ptr, bool r
if (!alloc->dimension.isValid())
strm.Printf("unknown\n");
else
- strm.Printf("(%d, %d, %d)\n", alloc->dimension.get()->dim_1,
- alloc->dimension.get()->dim_2,
- alloc->dimension.get()->dim_3);
+ strm.Printf("(%" PRId32 ", %" PRId32 ", %" PRId32 ")\n",
+ alloc->dimension.get()->dim_1, alloc->dimension.get()->dim_2, alloc->dimension.get()->dim_3);
strm.Indent("Data Type: ");
if (!alloc->element.type.isValid() || !alloc->element.type_vec_size.isValid())
@@ -2905,13 +3122,16 @@ RenderScriptRuntime::ListAllocations(Stream &strm, StackFrame* frame_ptr, bool r
{
// Enum value isn't monotonous, so doesn't always index RsDataTypeToString array
if (type >= Element::RS_TYPE_ELEMENT && type <= Element::RS_TYPE_FONT)
- type = static_cast<Element::DataType>((type - Element::RS_TYPE_ELEMENT) + Element::RS_TYPE_MATRIX_2X2 + 1);
+ type = static_cast<Element::DataType>((type - Element::RS_TYPE_ELEMENT) +
+ Element::RS_TYPE_MATRIX_2X2 + 1);
- if (type >= (sizeof(AllocationDetails::RsDataTypeToString) / sizeof(AllocationDetails::RsDataTypeToString[0]))
- || vector_size > 4 || vector_size < 1)
+ if (type >= (sizeof(AllocationDetails::RsDataTypeToString) /
+ sizeof(AllocationDetails::RsDataTypeToString[0])) ||
+ vector_size > 4 || vector_size < 1)
strm.Printf("invalid type\n");
else
- strm.Printf("%s\n", AllocationDetails::RsDataTypeToString[static_cast<unsigned int>(type)][vector_size-1]);
+ strm.Printf("%s\n", AllocationDetails::RsDataTypeToString[static_cast<uint32_t>(type)]
+ [vector_size - 1]);
}
}
@@ -2924,7 +3144,7 @@ RenderScriptRuntime::ListAllocations(Stream &strm, StackFrame* frame_ptr, bool r
if (kind < Element::RS_KIND_USER || kind > Element::RS_KIND_PIXEL_YUV)
strm.Printf("invalid kind\n");
else
- strm.Printf("%s\n", AllocationDetails::RsDataKindToString[static_cast<unsigned int>(kind)]);
+ strm.Printf("%s\n", AllocationDetails::RsDataKindToString[static_cast<uint32_t>(kind)]);
}
strm.EOL();
@@ -2955,7 +3175,7 @@ RenderScriptRuntime::BreakOnModuleKernels(const RSModuleDescriptorSP rsmodule_sp
void
RenderScriptRuntime::SetBreakAllKernels(bool do_break, TargetSP target)
{
- Log* log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_LANGUAGE | LIBLLDB_LOG_BREAKPOINTS));
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_LANGUAGE | LIBLLDB_LOG_BREAKPOINTS));
InitSearchFilter(target);
@@ -2968,29 +3188,28 @@ RenderScriptRuntime::SetBreakAllKernels(bool do_break, TargetSP target)
BreakOnModuleKernels(module);
if (log)
- log->Printf("RenderScriptRuntime::SetBreakAllKernels(True)"
- "- breakpoints set on all currently loaded kernels");
+ log->Printf("%s(True) - breakpoints set on all currently loaded kernels.", __FUNCTION__);
}
else if (!do_break && m_breakAllKernels) // Breakpoints won't be set on any new kernels.
{
m_breakAllKernels = false;
if (log)
- log->Printf("RenderScriptRuntime::SetBreakAllKernels(False) - breakpoints no longer automatically set");
+ log->Printf("%s(False) - breakpoints no longer automatically set.", __FUNCTION__);
}
}
// Given the name of a kernel this function creates a breakpoint using our
// own breakpoint resolver, and returns the Breakpoint shared pointer.
BreakpointSP
-RenderScriptRuntime::CreateKernelBreakpoint(const ConstString& name)
+RenderScriptRuntime::CreateKernelBreakpoint(const ConstString &name)
{
- Log* log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_LANGUAGE | LIBLLDB_LOG_BREAKPOINTS));
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_LANGUAGE | LIBLLDB_LOG_BREAKPOINTS));
if (!m_filtersp)
{
if (log)
- log->Printf("RenderScriptRuntime::CreateKernelBreakpoint - Error: No breakpoint search filter set");
+ log->Printf("%s - error, no breakpoint search filter set.", __FUNCTION__);
return nullptr;
}
@@ -3000,7 +3219,7 @@ RenderScriptRuntime::CreateKernelBreakpoint(const ConstString& name)
// Give RS breakpoints a specific name, so the user can manipulate them as a group.
Error err;
if (!bp->AddName("RenderScriptKernel", err) && log)
- log->Printf("RenderScriptRuntime::CreateKernelBreakpoint: Error setting break name, %s", err.AsCString());
+ log->Printf("%s - error setting break name, '%s'.", __FUNCTION__, err.AsCString());
return bp;
}
@@ -3009,41 +3228,113 @@ RenderScriptRuntime::CreateKernelBreakpoint(const ConstString& name)
// If this is possible it returns true and sets the uint64_t parameter to the variables unsigned value.
// Otherwise function returns false.
bool
-RenderScriptRuntime::GetFrameVarAsUnsigned(const StackFrameSP frame_sp, const char* var_name, uint64_t& val)
+RenderScriptRuntime::GetFrameVarAsUnsigned(const StackFrameSP frame_sp, const char *var_name, uint64_t &val)
{
- Log* log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_LANGUAGE));
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_LANGUAGE));
Error error;
VariableSP var_sp;
// Find variable in stack frame
- ValueObjectSP value_sp(frame_sp->GetValueForVariableExpressionPath(var_name,
- eNoDynamicValues,
- StackFrame::eExpressionPathOptionCheckPtrVsMember |
- StackFrame::eExpressionPathOptionsAllowDirectIVarAccess,
- var_sp,
- error));
+ ValueObjectSP value_sp(frame_sp->GetValueForVariableExpressionPath(
+ var_name, eNoDynamicValues,
+ StackFrame::eExpressionPathOptionCheckPtrVsMember | StackFrame::eExpressionPathOptionsAllowDirectIVarAccess,
+ var_sp, error));
if (!error.Success())
{
if (log)
- log->Printf("RenderScriptRuntime::GetFrameVarAsUnsigned - Error, couldn't find '%s' in frame", var_name);
-
+ log->Printf("%s - error, couldn't find '%s' in frame", __FUNCTION__, var_name);
return false;
}
- // Find the unsigned int value for the variable
+ // Find the uint32_t value for the variable
bool success = false;
val = value_sp->GetValueAsUnsigned(0, &success);
if (!success)
{
if (log)
- log->Printf("RenderScriptRuntime::GetFrameVarAsUnsigned - Error, couldn't parse '%s' as an unsigned int", var_name);
-
+ log->Printf("%s - error, couldn't parse '%s' as an uint32_t.", __FUNCTION__, var_name);
return false;
}
return true;
}
+// Function attempts to find the current coordinate of a kernel invocation by investigating the
+// values of frame variables in the .expand function. These coordinates are returned via the coord
+// array reference parameter. Returns true if the coordinates could be found, and false otherwise.
+bool
+RenderScriptRuntime::GetKernelCoordinate(RSCoordinate &coord, Thread *thread_ptr)
+{
+ static const std::string s_runtimeExpandSuffix(".expand");
+ static const std::array<const char *, 3> s_runtimeCoordVars{{"rsIndex", "p->current.y", "p->current.z"}};
+
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_LANGUAGE));
+
+ if (!thread_ptr)
+ {
+ if (log)
+ log->Printf("%s - Error, No thread pointer", __FUNCTION__);
+
+ return false;
+ }
+
+ // Walk the call stack looking for a function whose name has the suffix '.expand'
+ // and contains the variables we're looking for.
+ for (uint32_t i = 0; i < thread_ptr->GetStackFrameCount(); ++i)
+ {
+ if (!thread_ptr->SetSelectedFrameByIndex(i))
+ continue;
+
+ StackFrameSP frame_sp = thread_ptr->GetSelectedFrame();
+ if (!frame_sp)
+ continue;
+
+ // Find the function name
+ const SymbolContext sym_ctx = frame_sp->GetSymbolContext(false);
+ const char *func_name_cstr = sym_ctx.GetFunctionName().AsCString();
+ if (!func_name_cstr)
+ continue;
+
+ if (log)
+ log->Printf("%s - Inspecting function '%s'", __FUNCTION__, func_name_cstr);
+
+ // Check if function name has .expand suffix
+ std::string func_name(func_name_cstr);
+ const int length_difference = func_name.length() - s_runtimeExpandSuffix.length();
+ if (length_difference <= 0)
+ continue;
+
+ const int32_t has_expand_suffix = func_name.compare(length_difference,
+ s_runtimeExpandSuffix.length(),
+ s_runtimeExpandSuffix);
+
+ if (has_expand_suffix != 0)
+ continue;
+
+ if (log)
+ log->Printf("%s - Found .expand function '%s'", __FUNCTION__, func_name_cstr);
+
+ // Get values for variables in .expand frame that tell us the current kernel invocation
+ bool found_coord_variables = true;
+ assert(s_runtimeCoordVars.size() == coord.size());
+
+ for (uint32_t i = 0; i < coord.size(); ++i)
+ {
+ uint64_t value = 0;
+ if (!GetFrameVarAsUnsigned(frame_sp, s_runtimeCoordVars[i], value))
+ {
+ found_coord_variables = false;
+ break;
+ }
+ coord[i] = value;
+ }
+
+ if (found_coord_variables)
+ return true;
+ }
+ return false;
+}
+
// Callback when a kernel breakpoint hits and we're looking for a specific coordinate.
// Baton parameter contains a pointer to the target coordinate we want to break on.
// Function then checks the .expand frame for the current coordinate and breaks to user if it matches.
@@ -3051,61 +3342,46 @@ RenderScriptRuntime::GetFrameVarAsUnsigned(const StackFrameSP frame_sp, const ch
// Parameter 'break_loc_id' is the id for the BreakpointLocation which was hit,
// a single logical breakpoint can have multiple addresses.
bool
-RenderScriptRuntime::KernelBreakpointHit(void *baton, StoppointCallbackContext *ctx,
- user_id_t break_id, user_id_t break_loc_id)
+RenderScriptRuntime::KernelBreakpointHit(void *baton, StoppointCallbackContext *ctx, user_id_t break_id,
+ user_id_t break_loc_id)
{
- Log* log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_LANGUAGE | LIBLLDB_LOG_BREAKPOINTS));
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_LANGUAGE | LIBLLDB_LOG_BREAKPOINTS));
assert(baton && "Error: null baton in conditional kernel breakpoint callback");
// Coordinate we want to stop on
- const int* target_coord = static_cast<const int*>(baton);
+ const uint32_t *target_coord = static_cast<const uint32_t *>(baton);
if (log)
- log->Printf("RenderScriptRuntime::KernelBreakpointHit - Break ID %" PRIu64 ", target coord (%d, %d, %d)",
- break_id, target_coord[0], target_coord[1], target_coord[2]);
+ log->Printf("%s - Break ID %" PRIu64 ", (%" PRIu32 ", %" PRIu32 ", %" PRIu32 ")", __FUNCTION__, break_id,
+ target_coord[0], target_coord[1], target_coord[2]);
- // Go up one stack frame to .expand kernel
+ // Select current thread
ExecutionContext context(ctx->exe_ctx_ref);
- ThreadSP thread_sp = context.GetThreadSP();
- if (!thread_sp->SetSelectedFrameByIndex(1))
- {
- if (log)
- log->Printf("RenderScriptRuntime::KernelBreakpointHit - Error, couldn't go up stack frame");
-
- return false;
- }
+ Thread *thread_ptr = context.GetThreadPtr();
+ assert(thread_ptr && "Null thread pointer");
- StackFrameSP frame_sp = thread_sp->GetSelectedFrame();
- if (!frame_sp)
+ // Find current kernel invocation from .expand frame variables
+ RSCoordinate current_coord{}; // Zero initialise array
+ if (!GetKernelCoordinate(current_coord, thread_ptr))
{
if (log)
- log->Printf("RenderScriptRuntime::KernelBreakpointHit - Error, couldn't select .expand stack frame");
-
+ log->Printf("%s - Error, couldn't select .expand stack frame", __FUNCTION__);
return false;
}
- // Get values for variables in .expand frame that tell us the current kernel invocation
- const char* coord_expressions[] = {"rsIndex", "p->current.y", "p->current.z"};
- uint64_t current_coord[3] = {0, 0, 0};
-
- for(int i = 0; i < 3; ++i)
- {
- if (!GetFrameVarAsUnsigned(frame_sp, coord_expressions[i], current_coord[i]))
- return false;
-
- if (log)
- log->Printf("RenderScriptRuntime::KernelBreakpointHit, %s = %" PRIu64, coord_expressions[i], current_coord[i]);
- }
+ if (log)
+ log->Printf("%s - (%" PRIu32 ",%" PRIu32 ",%" PRIu32 ")", __FUNCTION__, current_coord[0], current_coord[1],
+ current_coord[2]);
// Check if the current kernel invocation coordinate matches our target coordinate
- if (current_coord[0] == static_cast<uint64_t>(target_coord[0]) &&
- current_coord[1] == static_cast<uint64_t>(target_coord[1]) &&
- current_coord[2] == static_cast<uint64_t>(target_coord[2]))
+ if (current_coord[0] == target_coord[0] &&
+ current_coord[1] == target_coord[1] &&
+ current_coord[2] == target_coord[2])
{
if (log)
- log->Printf("RenderScriptRuntime::KernelBreakpointHit, BREAKING %" PRIu64 ", %" PRIu64 ", %" PRIu64,
- current_coord[0], current_coord[1], current_coord[2]);
+ log->Printf("%s, BREAKING (%" PRIu32 ",%" PRIu32 ",%" PRIu32 ")", __FUNCTION__, current_coord[0],
+ current_coord[1], current_coord[2]);
BreakpointSP breakpoint_sp = context.GetTargetPtr()->GetBreakpointByID(break_id);
assert(breakpoint_sp != nullptr && "Error: Couldn't find breakpoint matching break id for callback");
@@ -3121,8 +3397,8 @@ RenderScriptRuntime::KernelBreakpointHit(void *baton, StoppointCallbackContext *
// Argument 'coords', represents a three dimensional coordinate which can be used to specify
// a single kernel instance to break on. If this is set then we add a callback to the breakpoint.
void
-RenderScriptRuntime::PlaceBreakpointOnKernel(Stream &strm, const char* name, const std::array<int,3> coords,
- Error& error, TargetSP target)
+RenderScriptRuntime::PlaceBreakpointOnKernel(Stream &strm, const char *name, const std::array<int, 3> coords,
+ Error &error, TargetSP target)
{
if (!name)
{
@@ -3138,11 +3414,12 @@ RenderScriptRuntime::PlaceBreakpointOnKernel(Stream &strm, const char* name, con
// We have a conditional breakpoint on a specific coordinate
if (coords[0] != -1)
{
- strm.Printf("Conditional kernel breakpoint on coordinate %d, %d, %d", coords[0], coords[1], coords[2]);
+ strm.Printf("Conditional kernel breakpoint on coordinate %" PRId32 ", %" PRId32 ", %" PRId32,
+ coords[0], coords[1], coords[2]);
strm.EOL();
// Allocate memory for the baton, and copy over coordinate
- int* baton = new int[3];
+ uint32_t *baton = new uint32_t[coords.size()];
baton[0] = coords[0]; baton[1] = coords[1]; baton[2] = coords[2];
// Create a callback that will be invoked everytime the breakpoint is hit.
@@ -3150,7 +3427,7 @@ RenderScriptRuntime::PlaceBreakpointOnKernel(Stream &strm, const char* name, con
bp->SetCallback(KernelBreakpointHit, baton, true);
// Store a shared pointer to the baton, so the memory will eventually be cleaned up after destruction
- m_conditional_breaks[bp->GetID()] = std::shared_ptr<int>(baton);
+ m_conditional_breaks[bp->GetID()] = std::shared_ptr<uint32_t>(baton);
}
if (bp)
@@ -3170,10 +3447,10 @@ RenderScriptRuntime::DumpModules(Stream &strm) const
strm.IndentLess();
}
-RenderScriptRuntime::ScriptDetails*
+RenderScriptRuntime::ScriptDetails *
RenderScriptRuntime::LookUpScript(addr_t address, bool create)
{
- for (const auto & s : m_scripts)
+ for (const auto &s : m_scripts)
{
if (s->script.isValid())
if (*s->script == address)
@@ -3189,10 +3466,10 @@ RenderScriptRuntime::LookUpScript(addr_t address, bool create)
return nullptr;
}
-RenderScriptRuntime::AllocationDetails*
+RenderScriptRuntime::AllocationDetails *
RenderScriptRuntime::LookUpAllocation(addr_t address, bool create)
{
- for (const auto & a : m_allocations)
+ for (const auto &a : m_allocations)
{
if (a->address.isValid())
if (*a->address == address)
@@ -3213,7 +3490,7 @@ RSModuleDescriptor::Dump(Stream &strm) const
{
strm.Indent();
m_module->GetFileSpec().Dump(&strm);
- if(m_module->GetNumCompileUnits())
+ if (m_module->GetNumCompileUnits())
{
strm.Indent("Debug info loaded.");
}
@@ -3240,7 +3517,7 @@ RSModuleDescriptor::Dump(Stream &strm) const
{
kernel.Dump(strm);
}
- strm.Printf("Pragmas: %" PRIu64 , static_cast<uint64_t>(m_pragmas.size()));
+ strm.Printf("Pragmas: %" PRIu64, static_cast<uint64_t>(m_pragmas.size()));
strm.EOL();
strm.IndentMore();
for (const auto &key_val : m_pragmas)
@@ -3261,7 +3538,7 @@ RSGlobalDescriptor::Dump(Stream &strm) const
{
auto var = var_list.GetVariableAtIndex(0);
auto type = var->GetType();
- if(type)
+ if (type)
{
strm.Printf(" - ");
type->DumpTypeName(&strm);
@@ -3274,7 +3551,7 @@ RSGlobalDescriptor::Dump(Stream &strm) const
else
{
strm.Printf(" - variable identified, but not found in binary");
- const Symbol* s = m_module->m_module->FindFirstSymbolWithNameAndType(m_name, eSymbolTypeData);
+ const Symbol *s = m_module->m_module->FindFirstSymbolWithNameAndType(m_name, eSymbolTypeData);
if (s)
{
strm.Printf(" (symbol exists) ");
@@ -3291,44 +3568,6 @@ RSKernelDescriptor::Dump(Stream &strm) const
strm.EOL();
}
-class CommandObjectRenderScriptRuntimeModuleProbe : public CommandObjectParsed
-{
-public:
- CommandObjectRenderScriptRuntimeModuleProbe(CommandInterpreter &interpreter)
- : CommandObjectParsed(interpreter, "renderscript module probe",
- "Initiates a Probe of all loaded modules for kernels and other renderscript objects.",
- "renderscript module probe",
- eCommandRequiresTarget | eCommandRequiresProcess | eCommandProcessMustBeLaunched)
- {
- }
-
- ~CommandObjectRenderScriptRuntimeModuleProbe() override = default;
-
- bool
- DoExecute(Args &command, CommandReturnObject &result) override
- {
- const size_t argc = command.GetArgumentCount();
- if (argc == 0)
- {
- Target *target = m_exe_ctx.GetTargetPtr();
- RenderScriptRuntime *runtime =
- (RenderScriptRuntime *)m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(eLanguageTypeExtRenderScript);
- auto module_list = target->GetImages();
- bool new_rs_details = runtime->ProbeModules(module_list);
- if (new_rs_details)
- {
- result.AppendMessage("New renderscript modules added to runtime model.");
- }
- result.SetStatus(eReturnStatusSuccessFinishResult);
- return true;
- }
-
- result.AppendErrorWithFormat("'%s' takes no arguments", m_cmd_name.c_str());
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
-};
-
class CommandObjectRenderScriptRuntimeModuleDump : public CommandObjectParsed
{
public:
@@ -3356,10 +3595,9 @@ class CommandObjectRenderScriptRuntimeModule : public CommandObjectMultiword
{
public:
CommandObjectRenderScriptRuntimeModule(CommandInterpreter &interpreter)
- : CommandObjectMultiword(interpreter, "renderscript module", "Commands that deal with renderscript modules.",
- NULL)
+ : CommandObjectMultiword(interpreter, "renderscript module", "Commands that deal with RenderScript modules.",
+ nullptr)
{
- LoadSubCommand("probe", CommandObjectSP(new CommandObjectRenderScriptRuntimeModuleProbe(interpreter)));
LoadSubCommand("dump", CommandObjectSP(new CommandObjectRenderScriptRuntimeModuleDump(interpreter)));
}
@@ -3371,8 +3609,8 @@ class CommandObjectRenderScriptRuntimeKernelList : public CommandObjectParsed
public:
CommandObjectRenderScriptRuntimeKernelList(CommandInterpreter &interpreter)
: CommandObjectParsed(interpreter, "renderscript kernel list",
- "Lists renderscript kernel names and associated script resources.", "renderscript kernel list",
- eCommandRequiresProcess | eCommandProcessMustBeLaunched)
+ "Lists renderscript kernel names and associated script resources.",
+ "renderscript kernel list", eCommandRequiresProcess | eCommandProcessMustBeLaunched)
{
}
@@ -3394,14 +3632,16 @@ class CommandObjectRenderScriptRuntimeKernelBreakpointSet : public CommandObject
public:
CommandObjectRenderScriptRuntimeKernelBreakpointSet(CommandInterpreter &interpreter)
: CommandObjectParsed(interpreter, "renderscript kernel breakpoint set",
- "Sets a breakpoint on a renderscript kernel.", "renderscript kernel breakpoint set <kernel_name> [-c x,y,z]",
- eCommandRequiresProcess | eCommandProcessMustBeLaunched | eCommandProcessMustBePaused), m_options(interpreter)
+ "Sets a breakpoint on a renderscript kernel.",
+ "renderscript kernel breakpoint set <kernel_name> [-c x,y,z]",
+ eCommandRequiresProcess | eCommandProcessMustBeLaunched | eCommandProcessMustBePaused),
+ m_options(interpreter)
{
}
~CommandObjectRenderScriptRuntimeKernelBreakpointSet() override = default;
- Options*
+ Options *
GetOptions() override
{
return &m_options;
@@ -3410,9 +3650,7 @@ public:
class CommandOptions : public Options
{
public:
- CommandOptions(CommandInterpreter &interpreter) : Options(interpreter)
- {
- }
+ CommandOptions(CommandInterpreter &interpreter) : Options(interpreter) {}
~CommandOptions() override = default;
@@ -3426,7 +3664,8 @@ public:
{
case 'c':
if (!ParseCoordinate(option_arg))
- error.SetErrorStringWithFormat("Couldn't parse coordinate '%s', should be in format 'x,y,z'.", option_arg);
+ error.SetErrorStringWithFormat("Couldn't parse coordinate '%s', should be in format 'x,y,z'.",
+ option_arg);
break;
default:
error.SetErrorStringWithFormat("unrecognized option '%c'", short_option);
@@ -3439,23 +3678,23 @@ public:
// Where 'id_cstr' is this argument with the whitespace trimmed.
// Missing coordinates are defaulted to zero.
bool
- ParseCoordinate(const char* id_cstr)
+ ParseCoordinate(const char *id_cstr)
{
RegularExpression regex;
RegularExpression::Match regex_match(3);
bool matched = false;
- if(regex.Compile("^([0-9]+),([0-9]+),([0-9]+)$") && regex.Execute(id_cstr, &regex_match))
+ if (regex.Compile("^([0-9]+),([0-9]+),([0-9]+)$") && regex.Execute(id_cstr, &regex_match))
matched = true;
- else if(regex.Compile("^([0-9]+),([0-9]+)$") && regex.Execute(id_cstr, &regex_match))
+ else if (regex.Compile("^([0-9]+),([0-9]+)$") && regex.Execute(id_cstr, &regex_match))
matched = true;
- else if(regex.Compile("^([0-9]+)$") && regex.Execute(id_cstr, &regex_match))
+ else if (regex.Compile("^([0-9]+)$") && regex.Execute(id_cstr, &regex_match))
matched = true;
- for(uint32_t i = 0; i < 3; i++)
+ for (uint32_t i = 0; i < 3; i++)
{
std::string group;
- if(regex_match.GetMatchAtIndex(id_cstr, i + 1, group))
- m_coord[i] = (uint32_t)strtoul(group.c_str(), NULL, 0);
+ if (regex_match.GetMatchAtIndex(id_cstr, i + 1, group))
+ m_coord[i] = (uint32_t)strtoul(group.c_str(), nullptr, 0);
else
m_coord[i] = 0;
}
@@ -3471,14 +3710,14 @@ public:
m_coord[2] = -1;
}
- const OptionDefinition*
+ const OptionDefinition *
GetDefinitions() override
{
return g_option_table;
}
static OptionDefinition g_option_table[];
- std::array<int,3> m_coord;
+ std::array<int, 3> m_coord;
};
bool
@@ -3487,13 +3726,14 @@ public:
const size_t argc = command.GetArgumentCount();
if (argc < 1)
{
- result.AppendErrorWithFormat("'%s' takes 1 argument of kernel name, and an optional coordinate.", m_cmd_name.c_str());
+ result.AppendErrorWithFormat("'%s' takes 1 argument of kernel name, and an optional coordinate.",
+ m_cmd_name.c_str());
result.SetStatus(eReturnStatusFailed);
return false;
}
RenderScriptRuntime *runtime =
- (RenderScriptRuntime *)m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(eLanguageTypeExtRenderScript);
+ (RenderScriptRuntime *)m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(eLanguageTypeExtRenderScript);
Error error;
runtime->PlaceBreakpointOnKernel(result.GetOutputStream(), command.GetArgumentAtIndex(0), m_options.m_coord,
@@ -3514,26 +3754,24 @@ private:
CommandOptions m_options;
};
-OptionDefinition
-CommandObjectRenderScriptRuntimeKernelBreakpointSet::CommandOptions::g_option_table[] =
-{
- { LLDB_OPT_SET_1, false, "coordinate", 'c', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeValue,
- "Set a breakpoint on a single invocation of the kernel with specified coordinate.\n"
- "Coordinate takes the form 'x[,y][,z] where x,y,z are positive integers representing kernel dimensions. "
- "Any unset dimensions will be defaulted to zero."},
- { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
-};
+OptionDefinition CommandObjectRenderScriptRuntimeKernelBreakpointSet::CommandOptions::g_option_table[] = {
+ {LLDB_OPT_SET_1, false, "coordinate", 'c', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeValue,
+ "Set a breakpoint on a single invocation of the kernel with specified coordinate.\n"
+ "Coordinate takes the form 'x[,y][,z] where x,y,z are positive integers representing kernel dimensions. "
+ "Any unset dimensions will be defaulted to zero."},
+ {0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr}};
class CommandObjectRenderScriptRuntimeKernelBreakpointAll : public CommandObjectParsed
{
public:
CommandObjectRenderScriptRuntimeKernelBreakpointAll(CommandInterpreter &interpreter)
- : CommandObjectParsed(interpreter, "renderscript kernel breakpoint all",
- "Automatically sets a breakpoint on all renderscript kernels that are or will be loaded.\n"
- "Disabling option means breakpoints will no longer be set on any kernels loaded in the future, "
- "but does not remove currently set breakpoints.",
- "renderscript kernel breakpoint all <enable/disable>",
- eCommandRequiresProcess | eCommandProcessMustBeLaunched | eCommandProcessMustBePaused)
+ : CommandObjectParsed(
+ interpreter, "renderscript kernel breakpoint all",
+ "Automatically sets a breakpoint on all renderscript kernels that are or will be loaded.\n"
+ "Disabling option means breakpoints will no longer be set on any kernels loaded in the future, "
+ "but does not remove currently set breakpoints.",
+ "renderscript kernel breakpoint all <enable/disable>",
+ eCommandRequiresProcess | eCommandProcessMustBeLaunched | eCommandProcessMustBePaused)
{
}
@@ -3550,11 +3788,11 @@ public:
return false;
}
- RenderScriptRuntime *runtime =
- static_cast<RenderScriptRuntime *>(m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(eLanguageTypeExtRenderScript));
+ RenderScriptRuntime *runtime = static_cast<RenderScriptRuntime *>(
+ m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(eLanguageTypeExtRenderScript));
bool do_break = false;
- const char* argument = command.GetArgumentAtIndex(0);
+ const char *argument = command.GetArgumentAtIndex(0);
if (strcmp(argument, "enable") == 0)
{
do_break = true;
@@ -3579,12 +3817,48 @@ public:
}
};
+class CommandObjectRenderScriptRuntimeKernelCoordinate : public CommandObjectParsed
+{
+public:
+ CommandObjectRenderScriptRuntimeKernelCoordinate(CommandInterpreter &interpreter)
+ : CommandObjectParsed(interpreter, "renderscript kernel coordinate",
+ "Shows the (x,y,z) coordinate of the current kernel invocation.",
+ "renderscript kernel coordinate",
+ eCommandRequiresProcess | eCommandProcessMustBeLaunched | eCommandProcessMustBePaused)
+ {
+ }
+
+ ~CommandObjectRenderScriptRuntimeKernelCoordinate() override = default;
+
+ bool
+ DoExecute(Args &command, CommandReturnObject &result) override
+ {
+ RSCoordinate coord{}; // Zero initialize array
+ bool success = RenderScriptRuntime::GetKernelCoordinate(coord, m_exe_ctx.GetThreadPtr());
+ Stream &stream = result.GetOutputStream();
+
+ if (success)
+ {
+ stream.Printf("Coordinate: (%" PRIu32 ", %" PRIu32 ", %" PRIu32 ")", coord[0], coord[1], coord[2]);
+ stream.EOL();
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+ }
+ else
+ {
+ stream.Printf("Error: Coordinate could not be found.");
+ stream.EOL();
+ result.SetStatus(eReturnStatusFailed);
+ }
+ return true;
+ }
+};
+
class CommandObjectRenderScriptRuntimeKernelBreakpoint : public CommandObjectMultiword
{
public:
CommandObjectRenderScriptRuntimeKernelBreakpoint(CommandInterpreter &interpreter)
- : CommandObjectMultiword(interpreter, "renderscript kernel", "Commands that generate breakpoints on renderscript kernels.",
- nullptr)
+ : CommandObjectMultiword(interpreter, "renderscript kernel",
+ "Commands that generate breakpoints on renderscript kernels.", nullptr)
{
LoadSubCommand("set", CommandObjectSP(new CommandObjectRenderScriptRuntimeKernelBreakpointSet(interpreter)));
LoadSubCommand("all", CommandObjectSP(new CommandObjectRenderScriptRuntimeKernelBreakpointAll(interpreter)));
@@ -3597,11 +3871,14 @@ class CommandObjectRenderScriptRuntimeKernel : public CommandObjectMultiword
{
public:
CommandObjectRenderScriptRuntimeKernel(CommandInterpreter &interpreter)
- : CommandObjectMultiword(interpreter, "renderscript kernel", "Commands that deal with renderscript kernels.",
- NULL)
+ : CommandObjectMultiword(interpreter, "renderscript kernel", "Commands that deal with RenderScript kernels.",
+ nullptr)
{
LoadSubCommand("list", CommandObjectSP(new CommandObjectRenderScriptRuntimeKernelList(interpreter)));
- LoadSubCommand("breakpoint", CommandObjectSP(new CommandObjectRenderScriptRuntimeKernelBreakpoint(interpreter)));
+ LoadSubCommand("coordinate",
+ CommandObjectSP(new CommandObjectRenderScriptRuntimeKernelCoordinate(interpreter)));
+ LoadSubCommand("breakpoint",
+ CommandObjectSP(new CommandObjectRenderScriptRuntimeKernelBreakpoint(interpreter)));
}
~CommandObjectRenderScriptRuntimeKernel() override = default;
@@ -3611,9 +3888,8 @@ class CommandObjectRenderScriptRuntimeContextDump : public CommandObjectParsed
{
public:
CommandObjectRenderScriptRuntimeContextDump(CommandInterpreter &interpreter)
- : CommandObjectParsed(interpreter, "renderscript context dump",
- "Dumps renderscript context information.", "renderscript context dump",
- eCommandRequiresProcess | eCommandProcessMustBeLaunched)
+ : CommandObjectParsed(interpreter, "renderscript context dump", "Dumps renderscript context information.",
+ "renderscript context dump", eCommandRequiresProcess | eCommandProcessMustBeLaunched)
{
}
@@ -3634,8 +3910,8 @@ class CommandObjectRenderScriptRuntimeContext : public CommandObjectMultiword
{
public:
CommandObjectRenderScriptRuntimeContext(CommandInterpreter &interpreter)
- : CommandObjectMultiword(interpreter, "renderscript context", "Commands that deal with renderscript contexts.",
- NULL)
+ : CommandObjectMultiword(interpreter, "renderscript context", "Commands that deal with RenderScript contexts.",
+ nullptr)
{
LoadSubCommand("dump", CommandObjectSP(new CommandObjectRenderScriptRuntimeContextDump(interpreter)));
}
@@ -3649,13 +3925,14 @@ public:
CommandObjectRenderScriptRuntimeAllocationDump(CommandInterpreter &interpreter)
: CommandObjectParsed(interpreter, "renderscript allocation dump",
"Displays the contents of a particular allocation", "renderscript allocation dump <ID>",
- eCommandRequiresProcess | eCommandProcessMustBeLaunched), m_options(interpreter)
+ eCommandRequiresProcess | eCommandProcessMustBeLaunched),
+ m_options(interpreter)
{
}
~CommandObjectRenderScriptRuntimeAllocationDump() override = default;
- Options*
+ Options *
GetOptions() override
{
return &m_options;
@@ -3664,9 +3941,7 @@ public:
class CommandOptions : public Options
{
public:
- CommandOptions(CommandInterpreter &interpreter) : Options(interpreter)
- {
- }
+ CommandOptions(CommandInterpreter &interpreter) : Options(interpreter) {}
~CommandOptions() override = default;
@@ -3699,7 +3974,7 @@ public:
m_outfile.Clear();
}
- const OptionDefinition*
+ const OptionDefinition *
GetDefinitions() override
{
return g_option_table;
@@ -3721,10 +3996,10 @@ public:
return false;
}
- RenderScriptRuntime *runtime =
- static_cast<RenderScriptRuntime *>(m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(eLanguageTypeExtRenderScript));
+ RenderScriptRuntime *runtime = static_cast<RenderScriptRuntime *>(
+ m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(eLanguageTypeExtRenderScript));
- const char* id_cstr = command.GetArgumentAtIndex(0);
+ const char *id_cstr = command.GetArgumentAtIndex(0);
bool convert_complete = false;
const uint32_t id = StringConvert::ToUInt32(id_cstr, UINT32_MAX, 0, &convert_complete);
if (!convert_complete)
@@ -3734,7 +4009,7 @@ public:
return false;
}
- Stream* output_strm = nullptr;
+ Stream *output_strm = nullptr;
StreamFile outfile_stream;
const FileSpec &outfile_spec = m_options.m_outfile; // Dump allocation to file instead
if (outfile_spec)
@@ -3773,13 +4048,10 @@ private:
CommandOptions m_options;
};
-OptionDefinition
-CommandObjectRenderScriptRuntimeAllocationDump::CommandOptions::g_option_table[] =
-{
- { LLDB_OPT_SET_1, false, "file", 'f', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeFilename,
- "Print results to specified file instead of command line."},
- { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
-};
+OptionDefinition CommandObjectRenderScriptRuntimeAllocationDump::CommandOptions::g_option_table[] = {
+ {LLDB_OPT_SET_1, false, "file", 'f', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeFilename,
+ "Print results to specified file instead of command line."},
+ {0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr}};
class CommandObjectRenderScriptRuntimeAllocationList : public CommandObjectParsed
{
@@ -3787,13 +4059,14 @@ public:
CommandObjectRenderScriptRuntimeAllocationList(CommandInterpreter &interpreter)
: CommandObjectParsed(interpreter, "renderscript allocation list",
"List renderscript allocations and their information.", "renderscript allocation list",
- eCommandRequiresProcess | eCommandProcessMustBeLaunched), m_options(interpreter)
+ eCommandRequiresProcess | eCommandProcessMustBeLaunched),
+ m_options(interpreter)
{
}
~CommandObjectRenderScriptRuntimeAllocationList() override = default;
- Options*
+ Options *
GetOptions() override
{
return &m_options;
@@ -3802,9 +4075,7 @@ public:
class CommandOptions : public Options
{
public:
- CommandOptions(CommandInterpreter &interpreter) : Options(interpreter), m_refresh(false)
- {
- }
+ CommandOptions(CommandInterpreter &interpreter) : Options(interpreter), m_id(0) {}
~CommandOptions() override = default;
@@ -3816,8 +4087,11 @@ public:
switch (short_option)
{
- case 'r':
- m_refresh = true;
+ case 'i':
+ bool success;
+ m_id = StringConvert::ToUInt32(option_arg, 0, 0, &success);
+ if (!success)
+ error.SetErrorStringWithFormat("invalid integer value for option '%c'", short_option);
break;
default:
error.SetErrorStringWithFormat("unrecognized option '%c'", short_option);
@@ -3829,25 +4103,25 @@ public:
void
OptionParsingStarting() override
{
- m_refresh = false;
+ m_id = 0;
}
- const OptionDefinition*
+ const OptionDefinition *
GetDefinitions() override
{
return g_option_table;
}
static OptionDefinition g_option_table[];
- bool m_refresh;
+ uint32_t m_id;
};
bool
DoExecute(Args &command, CommandReturnObject &result) override
{
- RenderScriptRuntime *runtime =
- static_cast<RenderScriptRuntime *>(m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(eLanguageTypeExtRenderScript));
- runtime->ListAllocations(result.GetOutputStream(), m_exe_ctx.GetFramePtr(), m_options.m_refresh);
+ RenderScriptRuntime *runtime = static_cast<RenderScriptRuntime *>(
+ m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(eLanguageTypeExtRenderScript));
+ runtime->ListAllocations(result.GetOutputStream(), m_exe_ctx.GetFramePtr(), m_options.m_id);
result.SetStatus(eReturnStatusSuccessFinishResult);
return true;
}
@@ -3856,21 +4130,18 @@ private:
CommandOptions m_options;
};
-OptionDefinition
-CommandObjectRenderScriptRuntimeAllocationList::CommandOptions::g_option_table[] =
-{
- { LLDB_OPT_SET_1, false, "refresh", 'r', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
- "Recompute allocation details."},
- { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
-};
+OptionDefinition CommandObjectRenderScriptRuntimeAllocationList::CommandOptions::g_option_table[] = {
+ {LLDB_OPT_SET_1, false, "id", 'i', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeIndex,
+ "Only show details of a single allocation with specified id."},
+ {0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr}};
class CommandObjectRenderScriptRuntimeAllocationLoad : public CommandObjectParsed
{
public:
CommandObjectRenderScriptRuntimeAllocationLoad(CommandInterpreter &interpreter)
- : CommandObjectParsed(interpreter, "renderscript allocation load",
- "Loads renderscript allocation contents from a file.", "renderscript allocation load <ID> <filename>",
- eCommandRequiresProcess | eCommandProcessMustBeLaunched)
+ : CommandObjectParsed(
+ interpreter, "renderscript allocation load", "Loads renderscript allocation contents from a file.",
+ "renderscript allocation load <ID> <filename>", eCommandRequiresProcess | eCommandProcessMustBeLaunched)
{
}
@@ -3882,25 +4153,26 @@ public:
const size_t argc = command.GetArgumentCount();
if (argc != 2)
{
- result.AppendErrorWithFormat("'%s' takes 2 arguments, an allocation ID and filename to read from.", m_cmd_name.c_str());
+ result.AppendErrorWithFormat("'%s' takes 2 arguments, an allocation ID and filename to read from.",
+ m_cmd_name.c_str());
result.SetStatus(eReturnStatusFailed);
return false;
}
- RenderScriptRuntime *runtime =
- static_cast<RenderScriptRuntime *>(m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(eLanguageTypeExtRenderScript));
+ RenderScriptRuntime *runtime = static_cast<RenderScriptRuntime *>(
+ m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(eLanguageTypeExtRenderScript));
- const char* id_cstr = command.GetArgumentAtIndex(0);
+ const char *id_cstr = command.GetArgumentAtIndex(0);
bool convert_complete = false;
const uint32_t id = StringConvert::ToUInt32(id_cstr, UINT32_MAX, 0, &convert_complete);
if (!convert_complete)
{
- result.AppendErrorWithFormat ("invalid allocation id argument '%s'", id_cstr);
- result.SetStatus (eReturnStatusFailed);
+ result.AppendErrorWithFormat("invalid allocation id argument '%s'", id_cstr);
+ result.SetStatus(eReturnStatusFailed);
return false;
}
- const char* filename = command.GetArgumentAtIndex(1);
+ const char *filename = command.GetArgumentAtIndex(1);
bool success = runtime->LoadAllocation(result.GetOutputStream(), id, filename, m_exe_ctx.GetFramePtr());
if (success)
@@ -3916,9 +4188,9 @@ class CommandObjectRenderScriptRuntimeAllocationSave : public CommandObjectParse
{
public:
CommandObjectRenderScriptRuntimeAllocationSave(CommandInterpreter &interpreter)
- : CommandObjectParsed(interpreter, "renderscript allocation save",
- "Write renderscript allocation contents to a file.", "renderscript allocation save <ID> <filename>",
- eCommandRequiresProcess | eCommandProcessMustBeLaunched)
+ : CommandObjectParsed(
+ interpreter, "renderscript allocation save", "Write renderscript allocation contents to a file.",
+ "renderscript allocation save <ID> <filename>", eCommandRequiresProcess | eCommandProcessMustBeLaunched)
{
}
@@ -3930,25 +4202,26 @@ public:
const size_t argc = command.GetArgumentCount();
if (argc != 2)
{
- result.AppendErrorWithFormat("'%s' takes 2 arguments, an allocation ID and filename to read from.", m_cmd_name.c_str());
+ result.AppendErrorWithFormat("'%s' takes 2 arguments, an allocation ID and filename to read from.",
+ m_cmd_name.c_str());
result.SetStatus(eReturnStatusFailed);
return false;
}
- RenderScriptRuntime *runtime =
- static_cast<RenderScriptRuntime *>(m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(eLanguageTypeExtRenderScript));
+ RenderScriptRuntime *runtime = static_cast<RenderScriptRuntime *>(
+ m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(eLanguageTypeExtRenderScript));
- const char* id_cstr = command.GetArgumentAtIndex(0);
+ const char *id_cstr = command.GetArgumentAtIndex(0);
bool convert_complete = false;
const uint32_t id = StringConvert::ToUInt32(id_cstr, UINT32_MAX, 0, &convert_complete);
if (!convert_complete)
{
- result.AppendErrorWithFormat ("invalid allocation id argument '%s'", id_cstr);
- result.SetStatus (eReturnStatusFailed);
+ result.AppendErrorWithFormat("invalid allocation id argument '%s'", id_cstr);
+ result.SetStatus(eReturnStatusFailed);
return false;
}
- const char* filename = command.GetArgumentAtIndex(1);
+ const char *filename = command.GetArgumentAtIndex(1);
bool success = runtime->SaveAllocation(result.GetOutputStream(), id, filename, m_exe_ctx.GetFramePtr());
if (success)
@@ -3960,17 +4233,51 @@ public:
}
};
+class CommandObjectRenderScriptRuntimeAllocationRefresh : public CommandObjectParsed
+{
+public:
+ CommandObjectRenderScriptRuntimeAllocationRefresh(CommandInterpreter &interpreter)
+ : CommandObjectParsed(interpreter, "renderscript allocation refresh",
+ "Recomputes the details of all allocations.", "renderscript allocation refresh",
+ eCommandRequiresProcess | eCommandProcessMustBeLaunched)
+ {
+ }
+
+ ~CommandObjectRenderScriptRuntimeAllocationRefresh() override = default;
+
+ bool
+ DoExecute(Args &command, CommandReturnObject &result) override
+ {
+ RenderScriptRuntime *runtime = static_cast<RenderScriptRuntime *>(
+ m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(eLanguageTypeExtRenderScript));
+
+ bool success = runtime->RecomputeAllAllocations(result.GetOutputStream(), m_exe_ctx.GetFramePtr());
+
+ if (success)
+ {
+ result.SetStatus(eReturnStatusSuccessFinishResult);
+ return true;
+ }
+ else
+ {
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+ }
+};
+
class CommandObjectRenderScriptRuntimeAllocation : public CommandObjectMultiword
{
public:
CommandObjectRenderScriptRuntimeAllocation(CommandInterpreter &interpreter)
- : CommandObjectMultiword(interpreter, "renderscript allocation", "Commands that deal with renderscript allocations.",
- NULL)
+ : CommandObjectMultiword(interpreter, "renderscript allocation",
+ "Commands that deal with RenderScript allocations.", nullptr)
{
LoadSubCommand("list", CommandObjectSP(new CommandObjectRenderScriptRuntimeAllocationList(interpreter)));
LoadSubCommand("dump", CommandObjectSP(new CommandObjectRenderScriptRuntimeAllocationDump(interpreter)));
LoadSubCommand("save", CommandObjectSP(new CommandObjectRenderScriptRuntimeAllocationSave(interpreter)));
LoadSubCommand("load", CommandObjectSP(new CommandObjectRenderScriptRuntimeAllocationLoad(interpreter)));
+ LoadSubCommand("refresh", CommandObjectSP(new CommandObjectRenderScriptRuntimeAllocationRefresh(interpreter)));
}
~CommandObjectRenderScriptRuntimeAllocation() override = default;
@@ -3980,9 +4287,8 @@ class CommandObjectRenderScriptRuntimeStatus : public CommandObjectParsed
{
public:
CommandObjectRenderScriptRuntimeStatus(CommandInterpreter &interpreter)
- : CommandObjectParsed(interpreter, "renderscript status",
- "Displays current renderscript runtime status.", "renderscript status",
- eCommandRequiresProcess | eCommandProcessMustBeLaunched)
+ : CommandObjectParsed(interpreter, "renderscript status", "Displays current RenderScript runtime status.",
+ "renderscript status", eCommandRequiresProcess | eCommandProcessMustBeLaunched)
{
}
@@ -4003,7 +4309,7 @@ class CommandObjectRenderScriptRuntime : public CommandObjectMultiword
{
public:
CommandObjectRenderScriptRuntime(CommandInterpreter &interpreter)
- : CommandObjectMultiword(interpreter, "renderscript", "A set of commands for operating on renderscript.",
+ : CommandObjectMultiword(interpreter, "renderscript", "Commands for operating on the RenderScript runtime.",
"renderscript <subcommand> [<subcommand-options>]")
{
LoadSubCommand("module", CommandObjectSP(new CommandObjectRenderScriptRuntimeModule(interpreter)));
@@ -4023,21 +4329,18 @@ RenderScriptRuntime::Initiate()
}
RenderScriptRuntime::RenderScriptRuntime(Process *process)
- : lldb_private::CPPLanguageRuntime(process), m_initiated(false), m_debuggerPresentFlagged(false),
+ : lldb_private::CPPLanguageRuntime(process),
+ m_initiated(false),
+ m_debuggerPresentFlagged(false),
m_breakAllKernels(false)
{
ModulesDidLoad(process->GetTarget().GetImages());
}
lldb::CommandObjectSP
-RenderScriptRuntime::GetCommandObject(lldb_private::CommandInterpreter& interpreter)
+RenderScriptRuntime::GetCommandObject(lldb_private::CommandInterpreter &interpreter)
{
- static CommandObjectSP command_object;
- if(!command_object)
- {
- command_object.reset(new CommandObjectRenderScriptRuntime(interpreter));
- }
- return command_object;
+ return CommandObjectSP(new CommandObjectRenderScriptRuntime(interpreter));
}
RenderScriptRuntime::~RenderScriptRuntime() = default;
diff --git a/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.h b/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.h
index 2fe439017bbc..2a0839a1a78b 100644
--- a/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.h
+++ b/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.h
@@ -20,13 +20,15 @@
// Other libraries and framework includes
// Project includes
-#include "lldb/lldb-private.h"
-#include "lldb/Target/LanguageRuntime.h"
-#include "lldb/Target/CPPLanguageRuntime.h"
#include "lldb/Core/Module.h"
+#include "lldb/Target/CPPLanguageRuntime.h"
+#include "lldb/Target/LanguageRuntime.h"
+#include "lldb/lldb-private.h"
-namespace lldb_private {
-namespace lldb_renderscript {
+namespace lldb_private
+{
+namespace lldb_renderscript
+{
typedef uint32_t RSSlot;
class RSModuleDescriptor;
@@ -36,6 +38,7 @@ struct RSKernelDescriptor;
typedef std::shared_ptr<RSModuleDescriptor> RSModuleDescriptorSP;
typedef std::shared_ptr<RSGlobalDescriptor> RSGlobalDescriptorSP;
typedef std::shared_ptr<RSKernelDescriptor> RSKernelDescriptorSP;
+typedef std::array<uint32_t, 3> RSCoordinate;
// Breakpoint Resolvers decide where a breakpoint is placed,
// so having our own allows us to limit the search scope to RS kernel modules.
@@ -43,9 +46,8 @@ typedef std::shared_ptr<RSKernelDescriptor> RSKernelDescriptorSP;
class RSBreakpointResolver : public BreakpointResolver
{
public:
- RSBreakpointResolver(Breakpoint *bkpt, ConstString name):
- BreakpointResolver (bkpt, BreakpointResolver::NameResolver),
- m_kernel_name(name)
+ RSBreakpointResolver(Breakpoint *bkpt, ConstString name)
+ : BreakpointResolver(bkpt, BreakpointResolver::NameResolver), m_kernel_name(name)
{
}
@@ -62,10 +64,7 @@ public:
}
Searcher::CallbackReturn
- SearchCallback(SearchFilter &filter,
- SymbolContext &context,
- Address *addr,
- bool containing) override;
+ SearchCallback(SearchFilter &filter, SymbolContext &context, Address *addr, bool containing) override;
Searcher::Depth
GetDepth() override
@@ -88,13 +87,12 @@ struct RSKernelDescriptor
{
public:
RSKernelDescriptor(const RSModuleDescriptor *module, const char *name, uint32_t slot)
- : m_module(module)
- , m_name(name)
- , m_slot(slot)
+ : m_module(module), m_name(name), m_slot(slot)
{
}
- void Dump(Stream &strm) const;
+ void
+ Dump(Stream &strm) const;
const RSModuleDescriptor *m_module;
ConstString m_name;
@@ -104,13 +102,10 @@ public:
struct RSGlobalDescriptor
{
public:
- RSGlobalDescriptor(const RSModuleDescriptor *module, const char *name )
- : m_module(module)
- , m_name(name)
- {
- }
+ RSGlobalDescriptor(const RSModuleDescriptor *module, const char *name) : m_module(module), m_name(name) {}
- void Dump(Stream &strm) const;
+ void
+ Dump(Stream &strm) const;
const RSModuleDescriptor *m_module;
ConstString m_name;
@@ -119,16 +114,15 @@ public:
class RSModuleDescriptor
{
public:
- RSModuleDescriptor(const lldb::ModuleSP &module)
- : m_module(module)
- {
- }
+ RSModuleDescriptor(const lldb::ModuleSP &module) : m_module(module) {}
~RSModuleDescriptor() = default;
- bool ParseRSInfo();
+ bool
+ ParseRSInfo();
- void Dump(Stream &strm) const;
+ void
+ Dump(Stream &strm) const;
const lldb::ModuleSP m_module;
std::vector<RSKernelDescriptor> m_kernels;
@@ -156,105 +150,144 @@ public:
//------------------------------------------------------------------
// Static Functions
//------------------------------------------------------------------
- static void Initialize();
+ static void
+ Initialize();
- static void Terminate();
+ static void
+ Terminate();
- static lldb_private::LanguageRuntime *CreateInstance(Process *process, lldb::LanguageType language);
+ static lldb_private::LanguageRuntime *
+ CreateInstance(Process *process, lldb::LanguageType language);
- static lldb::CommandObjectSP GetCommandObject(CommandInterpreter& interpreter);
+ static lldb::CommandObjectSP
+ GetCommandObject(CommandInterpreter &interpreter);
- static lldb_private::ConstString GetPluginNameStatic();
+ static lldb_private::ConstString
+ GetPluginNameStatic();
- static bool IsRenderScriptModule(const lldb::ModuleSP &module_sp);
+ static bool
+ IsRenderScriptModule(const lldb::ModuleSP &module_sp);
- static ModuleKind GetModuleKind(const lldb::ModuleSP &module_sp);
+ static ModuleKind
+ GetModuleKind(const lldb::ModuleSP &module_sp);
- static void ModulesDidLoad(const lldb::ProcessSP& process_sp, const ModuleList &module_list );
+ static void
+ ModulesDidLoad(const lldb::ProcessSP &process_sp, const ModuleList &module_list);
- bool IsVTableName(const char *name) override;
+ bool
+ IsVTableName(const char *name) override;
+
+ bool
+ GetDynamicTypeAndAddress(ValueObject &in_value, lldb::DynamicValueType use_dynamic,
+ TypeAndOrName &class_type_or_name, Address &address,
+ Value::ValueType &value_type) override;
- bool GetDynamicTypeAndAddress(ValueObject &in_value, lldb::DynamicValueType use_dynamic,
- TypeAndOrName &class_type_or_name, Address &address,
- Value::ValueType &value_type) override;
-
TypeAndOrName
- FixUpDynamicType(const TypeAndOrName& type_and_or_name,
- ValueObject& static_value) override;
+ FixUpDynamicType(const TypeAndOrName &type_and_or_name, ValueObject &static_value) override;
- bool CouldHaveDynamicValue(ValueObject &in_value) override;
+ bool
+ CouldHaveDynamicValue(ValueObject &in_value) override;
- lldb::BreakpointResolverSP CreateExceptionResolver(Breakpoint *bkpt, bool catch_bp, bool throw_bp) override;
+ lldb::BreakpointResolverSP
+ CreateExceptionResolver(Breakpoint *bkpt, bool catch_bp, bool throw_bp) override;
- bool LoadModule(const lldb::ModuleSP &module_sp);
+ bool
+ LoadModule(const lldb::ModuleSP &module_sp);
- bool ProbeModules(const ModuleList module_list);
+ void
+ DumpModules(Stream &strm) const;
- void DumpModules(Stream &strm) const;
+ void
+ DumpContexts(Stream &strm) const;
- void DumpContexts(Stream &strm) const;
+ void
+ DumpKernels(Stream &strm) const;
- void DumpKernels(Stream &strm) const;
+ bool
+ DumpAllocation(Stream &strm, StackFrame *frame_ptr, const uint32_t id);
- bool DumpAllocation(Stream &strm, StackFrame* frame_ptr, const uint32_t id);
+ void
+ ListAllocations(Stream &strm, StackFrame *frame_ptr, const uint32_t index);
- void ListAllocations(Stream &strm, StackFrame* frame_ptr, bool recompute);
+ bool
+ RecomputeAllAllocations(Stream &strm, StackFrame *frame_ptr);
- void PlaceBreakpointOnKernel(Stream &strm, const char *name, const std::array<int,3> coords,
- Error &error, lldb::TargetSP target);
+ void
+ PlaceBreakpointOnKernel(Stream &strm, const char *name, const std::array<int, 3> coords, Error &error,
+ lldb::TargetSP target);
- void SetBreakAllKernels(bool do_break, lldb::TargetSP target);
+ void
+ SetBreakAllKernels(bool do_break, lldb::TargetSP target);
- void Status(Stream &strm) const;
+ void
+ Status(Stream &strm) const;
- void ModulesDidLoad(const ModuleList &module_list) override;
+ void
+ ModulesDidLoad(const ModuleList &module_list) override;
- bool LoadAllocation(Stream &strm, const uint32_t alloc_id, const char* filename, StackFrame* frame_ptr);
+ bool
+ LoadAllocation(Stream &strm, const uint32_t alloc_id, const char *filename, StackFrame *frame_ptr);
- bool SaveAllocation(Stream &strm, const uint32_t alloc_id, const char* filename, StackFrame* frame_ptr);
+ bool
+ SaveAllocation(Stream &strm, const uint32_t alloc_id, const char *filename, StackFrame *frame_ptr);
- void Update();
+ void
+ Update();
- void Initiate();
+ void
+ Initiate();
//------------------------------------------------------------------
// PluginInterface protocol
//------------------------------------------------------------------
- lldb_private::ConstString GetPluginName() override;
+ lldb_private::ConstString
+ GetPluginName() override;
+
+ uint32_t
+ GetPluginVersion() override;
- uint32_t GetPluginVersion() override;
+ static bool
+ GetKernelCoordinate(lldb_renderscript::RSCoordinate &coord, Thread *thread_ptr);
protected:
struct ScriptDetails;
struct AllocationDetails;
struct Element;
- void InitSearchFilter(lldb::TargetSP target)
+ void
+ InitSearchFilter(lldb::TargetSP target)
{
if (!m_filtersp)
m_filtersp.reset(new SearchFilterForUnconstrainedSearches(target));
}
- void FixupScriptDetails(lldb_renderscript::RSModuleDescriptorSP rsmodule_sp);
+ void
+ FixupScriptDetails(lldb_renderscript::RSModuleDescriptorSP rsmodule_sp);
- void LoadRuntimeHooks(lldb::ModuleSP module, ModuleKind kind);
+ void
+ LoadRuntimeHooks(lldb::ModuleSP module, ModuleKind kind);
- bool RefreshAllocation(AllocationDetails* allocation, StackFrame* frame_ptr);
+ bool
+ RefreshAllocation(AllocationDetails *allocation, StackFrame *frame_ptr);
- bool EvalRSExpression(const char* expression, StackFrame* frame_ptr, uint64_t* result);
+ bool
+ EvalRSExpression(const char *expression, StackFrame *frame_ptr, uint64_t *result);
- lldb::BreakpointSP CreateKernelBreakpoint(const ConstString& name);
+ lldb::BreakpointSP
+ CreateKernelBreakpoint(const ConstString &name);
+
+ void
+ BreakOnModuleKernels(const lldb_renderscript::RSModuleDescriptorSP rsmodule_sp);
- void BreakOnModuleKernels(const lldb_renderscript::RSModuleDescriptorSP rsmodule_sp);
-
struct RuntimeHook;
- typedef void (RenderScriptRuntime::*CaptureStateFn)(RuntimeHook* hook_info, ExecutionContext &context); // Please do this!
+ typedef void (RenderScriptRuntime::*CaptureStateFn)(RuntimeHook *hook_info,
+ ExecutionContext &context); // Please do this!
struct HookDefn
{
- const char * name;
- const char * symbol_name_m32; // mangled name for the 32 bit architectures
- const char * symbol_name_m64; // mangled name for the 64 bit archs
+ const char *name;
+ const char *symbol_name_m32; // mangled name for the 32 bit architectures
+ const char *symbol_name_m64; // mangled name for the 64 bit archs
uint32_t version;
ModuleKind kind;
CaptureStateFn grabber;
@@ -263,7 +296,7 @@ protected:
struct RuntimeHook
{
lldb::addr_t address;
- const HookDefn *defn;
+ const HookDefn *defn;
lldb::BreakpointSP bp_sp;
};
@@ -279,7 +312,7 @@ protected:
std::map<lldb::addr_t, lldb_renderscript::RSModuleDescriptorSP> m_scriptMappings;
std::map<lldb::addr_t, RuntimeHookSP> m_runtimeHooks;
- std::map<lldb::user_id_t, std::shared_ptr<int>> m_conditional_breaks;
+ std::map<lldb::user_id_t, std::shared_ptr<uint32_t>> m_conditional_breaks;
lldb::SearchFilterSP m_filtersp; // Needed to create breakpoints through Target API
@@ -290,81 +323,93 @@ protected:
static const size_t s_runtimeHookCount;
private:
- // Used to index expression format strings
- enum ExpressionStrings
- {
- eExprGetOffsetPtr = 0,
- eExprAllocGetType,
- eExprTypeDimX,
- eExprTypeDimY,
- eExprTypeDimZ,
- eExprTypeElemPtr,
- eExprElementType,
- eExprElementKind,
- eExprElementVec,
- eExprElementFieldCount,
- eExprSubelementsId,
- eExprSubelementsName,
- eExprSubelementsArrSize
- };
-
RenderScriptRuntime(Process *process); // Call CreateInstance instead.
- static bool HookCallback(void *baton, StoppointCallbackContext *ctx, lldb::user_id_t break_id,
- lldb::user_id_t break_loc_id);
+ static bool
+ HookCallback(void *baton, StoppointCallbackContext *ctx, lldb::user_id_t break_id, lldb::user_id_t break_loc_id);
- static bool KernelBreakpointHit(void *baton, StoppointCallbackContext *ctx,
- lldb::user_id_t break_id, lldb::user_id_t break_loc_id);
+ static bool
+ KernelBreakpointHit(void *baton, StoppointCallbackContext *ctx, lldb::user_id_t break_id,
+ lldb::user_id_t break_loc_id);
- void HookCallback(RuntimeHook* hook_info, ExecutionContext& context);
+ void
+ HookCallback(RuntimeHook *hook_info, ExecutionContext &context);
- bool GetArgSimple(ExecutionContext& context, uint32_t arg, uint64_t* data);
+ void
+ CaptureScriptInit(RuntimeHook *hook_info, ExecutionContext &context);
- void CaptureScriptInit1(RuntimeHook* hook_info, ExecutionContext& context);
- void CaptureAllocationInit1(RuntimeHook* hook_info, ExecutionContext& context);
- void CaptureAllocationDestroy(RuntimeHook* hook_info, ExecutionContext& context);
- void CaptureSetGlobalVar1(RuntimeHook* hook_info, ExecutionContext& context);
+ void
+ CaptureAllocationInit(RuntimeHook *hook_info, ExecutionContext &context);
+
+ void
+ CaptureAllocationDestroy(RuntimeHook *hook_info, ExecutionContext &context);
+
+ void
+ CaptureSetGlobalVar(RuntimeHook *hook_info, ExecutionContext &context);
+
+ void
+ CaptureScriptInvokeForEachMulti(RuntimeHook *hook_info, ExecutionContext &context);
+
+ AllocationDetails *
+ FindAllocByID(Stream &strm, const uint32_t alloc_id);
+
+ std::shared_ptr<uint8_t>
+ GetAllocationData(AllocationDetails *allocation, StackFrame *frame_ptr);
+
+ void
+ SetElementSize(Element &elem);
+
+ static bool
+ GetFrameVarAsUnsigned(const lldb::StackFrameSP, const char *var_name, uint64_t &val);
+
+ void
+ FindStructTypeName(Element &elem, StackFrame *frame_ptr);
- AllocationDetails* FindAllocByID(Stream &strm, const uint32_t alloc_id);
- std::shared_ptr<uint8_t> GetAllocationData(AllocationDetails* allocation, StackFrame* frame_ptr);
- void SetElementSize(Element& elem);
- static bool GetFrameVarAsUnsigned(const lldb::StackFrameSP, const char* var_name, uint64_t& val);
- void FindStructTypeName(Element& elem, StackFrame* frame_ptr);
+ size_t
+ PopulateElementHeaders(const std::shared_ptr<uint8_t> header_buffer, size_t offset, const Element &elem);
- size_t PopulateElementHeaders(const std::shared_ptr<uint8_t> header_buffer, size_t offset, const Element& elem);
- size_t CalculateElementHeaderSize(const Element& elem);
+ size_t
+ CalculateElementHeaderSize(const Element &elem);
//
// Helper functions for jitting the runtime
//
- const char* JITTemplate(ExpressionStrings e);
- bool JITDataPointer(AllocationDetails* allocation, StackFrame* frame_ptr,
- unsigned int x = 0, unsigned int y = 0, unsigned int z = 0);
+ bool
+ JITDataPointer(AllocationDetails *allocation, StackFrame *frame_ptr,
+ uint32_t x = 0, uint32_t y = 0, uint32_t z = 0);
- bool JITTypePointer(AllocationDetails* allocation, StackFrame* frame_ptr);
+ bool
+ JITTypePointer(AllocationDetails *allocation, StackFrame *frame_ptr);
- bool JITTypePacked(AllocationDetails* allocation, StackFrame* frame_ptr);
+ bool
+ JITTypePacked(AllocationDetails *allocation, StackFrame *frame_ptr);
- bool JITElementPacked(Element& elem, const lldb::addr_t context, StackFrame* frame_ptr);
+ bool
+ JITElementPacked(Element &elem, const lldb::addr_t context, StackFrame *frame_ptr);
- bool JITAllocationSize(AllocationDetails* allocation, StackFrame* frame_ptr);
+ bool
+ JITAllocationSize(AllocationDetails *allocation, StackFrame *frame_ptr);
- bool JITSubelements(Element& elem, const lldb::addr_t context, StackFrame* frame_ptr);
+ bool
+ JITSubelements(Element &elem, const lldb::addr_t context, StackFrame *frame_ptr);
- bool JITAllocationStride(AllocationDetails* allocation, StackFrame* frame_ptr);
+ bool
+ JITAllocationStride(AllocationDetails *allocation, StackFrame *frame_ptr);
// Search for a script detail object using a target address.
// If a script does not currently exist this function will return nullptr.
// If 'create' is true and there is no previous script with this address,
// then a new Script detail object will be created for this address and returned.
- ScriptDetails* LookUpScript(lldb::addr_t address, bool create);
+ ScriptDetails *
+ LookUpScript(lldb::addr_t address, bool create);
// Search for a previously saved allocation detail object using a target address.
// If an allocation does not exist for this address then nullptr will be returned.
// If 'create' is true and there is no previous allocation then a new allocation
// detail object will be created for this address and returned.
- AllocationDetails* LookUpAllocation(lldb::addr_t address, bool create);
+ AllocationDetails *
+ LookUpAllocation(lldb::addr_t address, bool create);
};
} // namespace lldb_private