[Lldb-commits] [Patch][Please Review] Add support for GNU indirect functions
matt.kopec at intel.com
Fri Jan 25 16:47:04 PST 2013
I agree that the expression parser is maybe doing more then it should. The problem I found with Module::FindSymbolsWithNameAndType is that it returns both actual symbols and dynamic symbols. I wasn't sure if this is intentional or not but to get the correct symbol, I had to search through the returned list to find the symbol with an address. Should the symbol table contain symbols of type code with 0x0 addresses or is FindSymbolsWithNameAndType in the wrong here?
Resolving the function can be done at a lower level as you say. If, say, I pass the symbol as a parameter to GetCallableLoadAddress, I can check there whether the symbol is indirect (or maybe check lower) and resolve the function otherwise proceed as normal. Since I have a Target pointer I should be able to access the Process pointer and make the inferior call.
I'm not sure I understand your explanation of GetCallableLoadAddress taking a thread parameter, I'm not sure why it would need one. If we currently call GetCallableLoadAddress for "strlen" on Linux, it will resolve to a legitimate address in libc.so. However, this address is for the "strlen" resolver function which will return to us the address of the "strlen" implementation. We need to decide whether to resolve the indirect function or do what GetCallableLoadAddress does based on whether the symbol is indirect.
Let me know the best way to proceed.
From: Sean Callanan [scallanan at apple.com]
Sent: Friday, January 25, 2013 5:35 PM
To: Kopec, Matt
Cc: lldb-commits at cs.uiuc.edu
Subject: Re: [Lldb-commits] [Patch][Please Review] Add support for GNU indirect functions
So if I understand you correctly there is no case for indirect symbols where the indirection isn't yet resolved in the inferior. It's just a matter of walking one step further through pointers. That should address my first concern.
My second concern is that the expression parser is being changed to
- search for non-NULL addresses, and
- resolve indirect functions
when it seems like both of these ought to be done lower down.
Right now, the expression parser (ClangExpressionDeclMap::GetFunctionAddress) uses Module::FindSymbolsWithNameAndType to find code symbols, and assumes that this list contains valid entries with addresses that actually are the callable addresses. I would expect that FindSymbolsWithNameAndType return Symbols that contain Addresses that can transparently be evaluated by the expression parser, no special-casing required. This would obviate any change on the part of GetFunctionAddress (and also AddOneFunction).
I understand that this is tricky because you need to be able to do an inferior call on a thread to get the value of the pointer. I'm fine if GetCallableLoadAddress takes a thread as an additional (optional!) argument and fails if you don't pass one in and we need to call a function to determine the resulting address. Greg may have his own opinion here :)
On Jan 25, 2013, at 12:24 PM, "Kopec, Matt" <matt.kopec at intel.com> wrote:
> Hi Sean,
> No problem, I'm fine with Mr. Kopec as well :)
> Resolution only occurs after we have found a symbol and find that it is indirect. There are two places where the resolution occurs.
> -In AddOneFunction, if the function can't be resolved then it won't be added. Actually, it will assert and abort lldb. I don't see a reason why a symbol can't be resolved but maybe there is a better way to handle this?
> -In GetFunctionAddress, we will fail if a function cannot be resolved in the target.
> For the case of calling a function that the program hasn't called yet, this should be fine, as long as the symbol can be found and resolved in the inferior/linked libraries.
> For instance, test/lang/c/strings/TestCString.py has this test:
> self.expect("expression -- (int)strlen(\"hello\")",
> startstr = "(int) $2 = 5")
> The binary generated for this test doesn't have a strlen call (strlen is an indirect function) and the test above works as expected.
> I'm not sure what else lldb could do to force resolution. This is probably the simplest way. I think this is something that should be done on an as needed basis rather then, for instance, resolving all the indirect function addresses when the symbol table is generated.
> Does this address your concerns?
> From: Sean Callanan [scallanan at apple.com]
> Sent: Friday, January 25, 2013 2:21 PM
> To: Kopec, Matt
> Cc: lldb-commits at cs.uiuc.edu
> Subject: Re: [Lldb-commits] [Patch][Please Review] Add support for GNU indirect functions
> Sorry, I should probably have addressed you as "Matt." I looked at the headers wrong :)
> On Jan 25, 2013, at 11:19 AM, Sean Callanan <scallanan at apple.com> wrote:
>> one thing I noticed is that it looks like if the indirect symbol hasn't been resolved yet in the underlying process, it looks like we just give up. What if the user wants to call a function that the program hasn't yet called? Are there cases where this would blow up? Is there something more that LLDB should be able to do to force resolution?
>> On Jan 18, 2013, at 2:33 PM, "Kopec, Matt" <matt.kopec at intel.com> wrote:
>>> Hi all,
>>> This patch allows indirect functions to work on Linux when evaluating expressions. I'm not sure if this is a feature supported on Mac OS X.
>>> This is needed to support some library functions such as strcat and strlen when used in an expression. If one of these functions are used, the function will run once in the context of the inferior, which after completion, will return the address of the actual implementation of the function.
>>> Some more details on indirect functions if interested: http://www.agner.org/optimize/blog/read.php?i=167
>>> lldb-commits mailing list
>>> lldb-commits at cs.uiuc.edu
>> lldb-commits mailing list
>> lldb-commits at cs.uiuc.edu
More information about the lldb-commits