[LLVMdev] [lld] adding demangler for symbol resolution

Nick Kledzik
2014-04-03T05:58:10Z

On Apr 2, 2014, at 11:02 AM, Shankar Easwaran wrote:

> On 4/2/2014 12:23 PM, Nick Kledzik wrote:
>> On Apr 1, 2014, at 9:19 PM, Shankar Easwaran wrote:
>>
>>> The API's that would be in LinkingContext would be :-
>>>
>>>        * virtual bool canDemangle()  = 0; // Does the flavor
provide a way to demangle symbol names ?
>>>        * virtual std::string demangle(StringRef symbolName) = 0; //
demangle the symbol name
>>>
>>> Thoughts / Suggestions ?
>> Wouldn't it be simpler to have one demangle() method that does
nothing (returns input string) if demangling is not available, the string is not
a mangled symbol, or demangling was turned off (--no-demangle).   Then, you just
wrap a demangle() call around every use.
> Are you mentioning that one demangle function in LinkingContext ?
Yes.  How do you expect clients to use your proposed canDemangle()/demangle()
interface?   Seems like it would always be:
  str = sym;
  if (ctx.canDemangle())
     str = ctx.demangle(sym);

My suggestion is to move the canDemangle functionality into demangle, so clients
just always use:
    str = ctx.demangle(sym);
and it returns the input string if a demangler is not available or is disabled.


>
> One demangle method wouldnt work as the ItaniumABI uses one method to
demangle, ARMCXXABI uses a different method, and MSVC uses a different one. I am
not sure about Mach-O here ?
Given that, how can we make an lld tool that cross builds the same as it on the
native system?  Are you thinking of writing your own demangler?  Or use whatever
one is natively available, and fall back to not demangling if the native
demangler cannot demangle the given symbol name (e.g. an MSVS symbol on when
running on linux).


>
>> The __cxa_demangle function has an odd interface that requires a malloc
allocated block.  Having demangle() return a std::string means yet another
allocation. We might not care if this is just used in diagnostic outputs, but a
more efficient way would be to pass the stream object to demangle and have it
write directly to the stream instead of creating a std::string.
> I dont know if diagnostics in clang, already redirect things directly to a
stream.
>
> May be for now, as an initial implementation, we can have a single demangle
function that returns a std::string.
Lets look at an example, lld currently has:
            llvm::errs() << "lld warning: shared library symbol
"
                              << curShLib->name()
                              << " has different load path in "
…

My ideal change would be to something like:

            llvm::errs() << "lld warning: shared library symbol
"
                              << ctx.demangle(curShLib->name())
                              << " has different load path in "
…

-Nick

>
> As part of this, I was thinking to cleanup the way the errors are displayed
to the user from the Resolver, we could have functions in SymbolTable with
>
> raiseError(SymbolErrorKind, filename, symbolname)
> raiseError(SymbolErrorKind, filename, symbolname, filename, symbolname)
>
> SymbolErrorKind :>
> MultipleDefinition
> Undefined
> GroupError
> Note (for tracing)
> ...
>
>
>> Seems like a demangling utility might be something to add at the LLVM
level.  Either directly to raw_ostream or a wrapper like format().
> I have browsed discussions in llvm related to this to move the demangler
function which is housed in libcxx, and I dont think there is a plan to move
that.
>
> I think the format() specifier would be one thing that would be useful, but
I am not sure on how different linking contexts in lld, could route calls with a
central format specifier.
>
> Can you share more info on this ?
>
> Thanks
>
> Shankar Easwaran
>
> --
> Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted
by the Linux Foundation
>