Just to mention: the manual function calling is not really meant for public 
consumption at this point. The API was just made to work with for a few simple 
function calls.

Doing this right would involve something like compiling a snippet of source 
code, then mentioning what we want to access and change in that source code. 
For example if you had code like:

const char *jit_source = R("
#define MAX_SEL_NAME_LEN 1024
char g_selector_name[MAX_SEL_NAME_LEN];

id call_selector_on_object (id obj)
{
        SEL sel = sel_registerName(g_selector_name);
        return objc_msgSend (obj, sel);
}
");

Then you would compile this expression into a new class like ClangJITCode 
(which would need to be written), have accessors on it to get variable values:

ClangJITCode jit_code(triple);

Error err = jit_code.Compile (jit_source);
if (err.Success())
{
    jit_code.Install (process);

    if (jit_code.SetVariableValue ("g_selector_name", "count"))
    {
        ValueList args;
        Value id_value;
        id_value.XXX(); // Initialize ID value with the correct value
        args.Append(id_value);
        err = jit_code.CallFunction ("call_selector_on_object", id_value);
        ...
    }
}

This would allow us to install more than one function at a time, keep them all 
in the process, and call each individual function as needed. This would be much 
more usable than the current model, but of course it will need to be written.

Greg


On Mar 5, 2013, at 8:48 AM, Carlo Kok <[email protected]> wrote:

> I want to do a msgSend so first I need a selector (Which needs an 
> NSString/CFString) so my first step was:
> 
> 
> FindSymbolsWithNameAndType(... "__CFStringMakeConstantString")
> 
> to get the pointer to the function (that goes fine)
> 
> ValueList args;
> Value strname((uint8_t*)value.c_str(), value.length() + 1);
> strname.SetContext(Value::eContextTypeClangType, 
> ast_context->GetCStringType(true));
> args.PushValue(strname);
> 
> auto rettype = ast_context->CreatePointerType 
> (ast_context->GetBuiltInType_void());
> 
> Value ret;
> ret.SetContext(Value::eContextTypeClangType, rettype);
> 
> ClangFunction func (*GetBestExecutionContextScope(),
>                    ast,
>                    rettype,
>                    *fn,
>                    args);
> 
>    func.InsertFunction(m_process, wrapper_struct_addr, error_stream);
> 
> 
> 
>    ExecutionResults results = func.ExecuteFunction (m_process,
>      &wrapper_struct_addr,
>      error_stream,
>      true,
>      0 /* no timeout */,
>      true,
>      true,
>      true,
>      ret);
> 
> 
> 
> 
> However this fails with a stop_reason exception, so I think I'm doing 
> something wrong. Is this the right way to pass a char* to the process on the 
> other side? If so, what could I be missing, if not, what is?
> 
> Thanks,
> 
> Carlo Kok
> _______________________________________________
> lldb-dev mailing list
> [email protected]
> http://lists.cs.uiuc.edu/mailman/listinfo/lldb-dev

_______________________________________________
lldb-dev mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/lldb-dev

Reply via email to