Re: [RFC 2/3] Record function descriptor address instead of function address in value

Ulrich Weigand
2016-10-28T18:41:32Z

Yao Qi wrote:
> On Mon, Oct 17, 2016 at 4:51 PM, Ulrich Weigand <uweigand@de.ibm.com> wrote:
> > ... and therefore this function cannot really be implemented on ppc64
> > in a fully-general way. In particular, when running stripped binaries
> > or code that is otherwise without symbols (e.g. JITted code etc.), this
> > conversion may not be possible.
>
> I don't expect convert_from_func_addr working in general, due to the
> reasons you mentioned. convert_from_func_addr is only used when
> symbol (from debug information) is available. If we want to GDB
> handle such complex expression evaluation correctly, debug
> information is required.

OK, that makes sense. If we have a symbol from debug information,
we probably should also have the msymbol.

> > B.t.w. note that there is already a similar function that attempts this
> > conversion (ppc-sysv-tdep.c:convert_code_addr_to_desc_addr), but it is
> > currently only used during inferior function calls, so it is not so
> > critical if it fails. (With your change, that function may actually
> > no longer be necessary at that place since values should already point
> > to function descriptors ...)
> >
>
> Yes, convert_from_func_addr is similar to convert_code_addr_to_desc_addr.
> I removed convert_code_addr_to_desc_addr, but it breaks ifunc
> inferior call in my experiment, because ifunc resolver gets the function
> address rather than function descriptor address, we still need
> convert_code_addr_to_desc_addr to get function descriptor address.

Huh? The ifunc resolver is supposed to return a function pointer,
which will be a descriptor address on ppc64. Aha, it seems the
problem is in GDB's implementaton of elf_gnu_ifunc_resolve_addr,
which calls gdbarch_convert_from_func_ptr_addr -- it really
shouldn't do this, we should keep descriptors as long as possible.

> > Your code already *mostly* does that, with the exception of symbol
> > addresses. I'm wondering whether we shouldn't push the change one
> > step further back and already store descriptor addresses in
> > SYMBOL_VALUE_ADDRESS. Note that this is currently already handled
> > somewhat inconsistenly on ppc64: msymbols already point to the
> > descriptor, and so do symbols read from stabs debug info; only
> > symbols read from DWARF debug info actually point to the code
> > address.
>
> I tried what you suggested, but failed. SYMBOL_VALUE_ADDRESS
> is used to get variable address, rather than function's address. We
> get function address from block (BLOCK_START), and get block
> from symbol (SYMBOL_BLOCK_VALUE). There is no good way to
> store function descriptor address in symbol.

OK, I see. Doing the conversion when looking up the symbol address
should be fine, then.

> How about doing this in a followup patch as an enhancement? My
> priority is to get this RFC acceptable, and make PPC64/ARM/MIPS
> works well. Propagate descriptor address and bug fixes can be done
> later.

Sure.

> > Those are a bit annoying. I think the underlying problem is that operati=
> ons
> > like "disass" or "x/i" really don't work on "values" in the original sense
> > but rather on "PC addresses". Maybe it would make sense to have those
> > function enable a special "mode" in the expression evaluator that would
> > change the conversion of functions to function pointers to use the code
> > address instead of the descriptor address?
> >
>
> I think about the special "mode" in the expression evaluation, but I
> suspect that there is a case in a single expression, function address
> is expected in some symbol, and descriptor address is expected in
> some other symbol, like,
>
> int func (int i) { return i;}
>
> (gdb) x/i func + func (1)
>
> the "func" is expected to be function address and the second "func"
> is expected to be function descriptor address. I had a heuristics that
> VALUE means function address if we do a pointer add with long type
> (valarith.c:value_ptradd). It works fine.

I see. This is a bit odd in that evaluating "main" would then return
a descriptor while "main + 1" would return a code address, which
means the caller is never really sure which one it gets.

I think the problem you describe above could still be made to work
with the special evalution mode, you'd just have to reset the mode
to the default when recursing into certain expression nodes, like
e.g. when evaluating the function operand of a OP_FUNCALL node.

Bye,
Ulrich

--
Dr. Ulrich Weigand
GNU/Linux compilers and toolchain
Ulrich.Weigand@de.ibm.com