[lldb-dev] llvm assertion while evaluating expressions for MIPS on Linux

Bhushan Attarde via lldb-dev lldb-dev at lists.llvm.org
Fri Oct 23 05:03:27 PDT 2015


Hi Greg,

Thanks for your reply.

There are different temporary symbols for different architectures and file formats.
As far as I could see, llvm::MCAsmInfo class has a member "PrivateGlobalPrefix" which specifies this temporary symbol.
The default value for PrivateGlobalPrefix is 'L' (for ELF it is ".L").
The subclasses of llvm::MCAsmInfo sets PrivateGlobalPrefix to whatever value they want to use for temporary symbol.
MIPS sets this to "$". (and X86/ARM uses ".L")

Since the function name "$__lldb_valid_pointer_check" starts with "$" it matches with PrivateGlobalPrefix for MIPS and hence it is marked as temporary.
Its fine for all x86/x86_64/arm and arm64 variants because they all use symbol other than "$" (i.e ".L") as their PrivateGlobalPrefix.

As you mentioned we cannot remove "$" from function name because it may conflict with symbols from system libraries or user binaries,
so do you think removing C Language linkage from function "$__lldb_valid_pointer_check" can be a solution? or do you have a better solution to this issue?

Regards,
Bhushan


-----Original Message-----
From: Greg Clayton [mailto:gclayton at apple.com] 
Sent: 20 October 2015 23:56
To: Greg Clayton
Cc: Bhushan Attarde; lldb-dev at lists.llvm.org
Subject: Re: [lldb-dev] llvm assertion while evaluating expressions for MIPS on Linux

My guess is that there is a different temporary symbol for differing architectures and possibly depending on which file format (mach-o or ELF) you are targeting. MIPS probably happens to use '$'. I know mach-o files use "L" as the temporary symbol prefix, ELF tends to use '.'. Not sure where this would be abstracted in LLVM or if it is just built into the assemblers directly for each arch... If you can find out where this can be detected within LLVM, we can make sure we don't use any temporary prefixes in symbol names and work around this issue. We need to make sure that any functions we generate and JIT up and insert into the program do not conflict with _any_ symbol that could be in any system libraries or user binaries. This is why we used '$' in the first place.

Greg

> On Oct 20, 2015, at 11:11 AM, Greg Clayton via lldb-dev <lldb-dev at lists.llvm.org> wrote:
> 
> What is this not happening on any other architecture? Is the "$" special for MIPS and not for other architectures? We really don't want to remove the '$' as we want the symbol to be unique. The '$' symbol is fine for all x86/x86_64/arm and arm64 variants...
> 
> Greg
> 
> 
>> On Oct 19, 2015, at 11:30 PM, Bhushan Attarde via lldb-dev <lldb-dev at lists.llvm.org> wrote:
>> 
>> Hi,
>> 
>> I am facing issue (llvm assertion) in evaluating expressions for MIPS on Linux.
>> 
>> (lldb) p fooptr(a,b)
>> lldb: /home/battarde/git/llvm/lib/MC/ELFObjectWriter.cpp:791: void {anonymous}::ELFObjectWriter::computeSymbolTable(llvm::MCAssembler&, const llvm::MCAsmLayout&, const SectionIndexMapTy&, const RevGroupMapTy&, {anonymous}::ELFObjectWriter::SectionOffsetsTy&): Assertion `Local || !Symbol.isTemporary()' failed.
>> 
>> I debugged it and found that, LLDB inserts calls to dynamic checker function for pointer validation at appropriate locations in expression’s IR.
>> 
>> The issue is that this checker function’s name (hard-coded in LLDB in lldb\source\Expression\IRDynamicChecks.cpp) starts with “$” i.e “$__lldb_valid_pointer_check”.
>> While creating a MCSymbol (MCContext::createSymbol() in 
>> llvm/lib/MC/MCContext.cpp) for this function llvm detects the name starts with “$” and marks that symbol as ‘temporary’ symbol (PrivateGlobalPrefix is '$' for MIPS) Further while computing a symbol table in ELFObjectWriter::computeSymbolTable() the assertion triggers because this symbol is 'temporary'.
>> 
>> I tried couple of things that solves this issue for MIPS.
>> 
>> 1. Remove '$' from the function name.
>> 2. Remove "C Language linkage" from the dynamic pointer validation 
>> function i.e the below piece of code in 
>> lldb\source\Expression\IRDynamicChecks.cpp
>> ---------------------------------------------------------------------
>> static const char g_valid_pointer_check_text[] = "extern \"C\" 
>> void\n"
>> "$__lldb_valid_pointer_check (unsigned char *$__lldb_arg_ptr)\n"
>> "{\n"
>> "    unsigned char $__lldb_local_val = *$__lldb_arg_ptr;\n"
>> "}";
>> ---------------------------------------------------------------------
>> -
>> 
>> becomes
>> 
>> --------------------------------------------------------------------
>> static const char g_valid_pointer_check_text[] = "void\n"
>> "$__lldb_valid_pointer_check (unsigned char *$__lldb_arg_ptr)\n"
>> "{\n"
>> "    unsigned char $__lldb_local_val = *$__lldb_arg_ptr;\n"
>> "}";
>> --------------------------------------------------------------------
>> 
>> Removing C Language linkage will enable mangling and will mangle "$__lldb_valid_pointer_check" to something like "_Z27$__lldb_valid_pointer_checkPh".
>> So the mangled name won't start with '$' and the symbol will not be marked as Temporary and hence assertion won't be triggered.
>> 
>> Please let me know if there is any better solution to this issue.
>> 
>> Regards,
>> Bhushan
>> _______________________________________________
>> lldb-dev mailing list
>> lldb-dev at lists.llvm.org
>> http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-dev
> 
> _______________________________________________
> lldb-dev mailing list
> lldb-dev at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-dev



More information about the lldb-dev mailing list