forked from OSchip/llvm-project
117 lines
3.4 KiB
C++
117 lines
3.4 KiB
C++
//===-- ObjCObjectPrinter.cpp -------------------------------------*- C++ -*-===//
|
|
//
|
|
// The LLVM Compiler Infrastructure
|
|
//
|
|
// This file is distributed under the University of Illinois Open Source
|
|
// License. See LICENSE.TXT for details.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// C Includes
|
|
// C++ Includes
|
|
// Other libraries and framework includes
|
|
// Project includes
|
|
#include "lldb/Core/StreamString.h"
|
|
#include "lldb/Expression/ClangFunction.h"
|
|
#include "lldb/Target/ExecutionContext.h"
|
|
#include "lldb/Target/Process.h"
|
|
#include "lldb/Target/Target.h"
|
|
|
|
#include "lldb/Target/ObjCObjectPrinter.h"
|
|
|
|
using namespace lldb;
|
|
using namespace lldb_private;
|
|
|
|
//----------------------------------------------------------------------
|
|
// ObjCObjectPrinter constructor
|
|
//----------------------------------------------------------------------
|
|
ObjCObjectPrinter::ObjCObjectPrinter (Process &process) :
|
|
m_process(process)
|
|
{
|
|
}
|
|
|
|
//----------------------------------------------------------------------
|
|
// Destructor
|
|
//----------------------------------------------------------------------
|
|
ObjCObjectPrinter::~ObjCObjectPrinter ()
|
|
{
|
|
}
|
|
|
|
bool
|
|
ObjCObjectPrinter::PrintObject (ConstString &str, Value &object_ptr, ExecutionContext &exe_ctx)
|
|
{
|
|
if (!exe_ctx.process)
|
|
return false;
|
|
|
|
const Address *function_address = GetPrintForDebuggerAddr();
|
|
|
|
if (!function_address)
|
|
return false;
|
|
|
|
const char *target_triple = exe_ctx.process->GetTargetTriple().GetCString();
|
|
ClangASTContext *ast_context = exe_ctx.target->GetScratchClangASTContext();
|
|
|
|
void *return_qualtype = ast_context->GetCStringType(true);
|
|
Value ret;
|
|
ret.SetContext(Value::eContextTypeOpaqueClangQualType, return_qualtype);
|
|
|
|
ValueList arg_value_list;
|
|
arg_value_list.PushValue(object_ptr);
|
|
|
|
ClangFunction func(target_triple, ast_context, return_qualtype, *function_address, arg_value_list);
|
|
StreamString error_stream;
|
|
|
|
lldb::addr_t wrapper_struct_addr = LLDB_INVALID_ADDRESS;
|
|
func.InsertFunction(exe_ctx, wrapper_struct_addr, error_stream);
|
|
// FIXME: Check result of ExecuteFunction.
|
|
func.ExecuteFunction(exe_ctx, &wrapper_struct_addr, error_stream, true, 1000, true, ret);
|
|
|
|
addr_t result_ptr = ret.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
|
|
|
|
// poor man's strcpy
|
|
|
|
Error error;
|
|
std::vector<char> desc;
|
|
while (1)
|
|
{
|
|
char byte = '\0';
|
|
if (exe_ctx.process->ReadMemory(result_ptr + desc.size(), &byte, 1, error) != 1)
|
|
break;
|
|
|
|
desc.push_back(byte);
|
|
|
|
if (byte == '\0')
|
|
break;
|
|
}
|
|
|
|
if (!desc.empty())
|
|
{
|
|
str.SetCString(&desc.front());
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
Address *
|
|
ObjCObjectPrinter::GetPrintForDebuggerAddr()
|
|
{
|
|
if (!m_PrintForDebugger_addr.get())
|
|
{
|
|
ModuleList &modules = m_process.GetTarget().GetImages();
|
|
|
|
SymbolContextList contexts;
|
|
SymbolContext context;
|
|
|
|
if((!modules.FindSymbolsWithNameAndType(ConstString ("_NSPrintForDebugger"), eSymbolTypeCode, contexts)) &&
|
|
(!modules.FindSymbolsWithNameAndType(ConstString ("_CFPrintForDebugger"), eSymbolTypeCode, contexts)))
|
|
return NULL;
|
|
|
|
contexts.GetContextAtIndex(0, context);
|
|
|
|
m_PrintForDebugger_addr.reset(new Address(context.symbol->GetValue()));
|
|
}
|
|
|
|
return m_PrintForDebugger_addr.get();
|
|
}
|
|
|