[Bug default/19949] Compare locations of function arguments in libabigail
woodard at redhat dot com
sourceware-bugzilla@sourceware.org
Sun Jan 1 00:00:00 GMT 2017
https://sourceware.org/bugzilla/show_bug.cgi?id=19949
--- Comment #2 from Ben Woodard <woodard at redhat dot com> ---
09:36 Dodji: neb: first, I need to think more thoroughly about what we can do
with the information we already have. That is, the location of the parameter
argument (the DW_AT_location of the DW_TAG_formal_parameter), and also the
GNU_call_site_parameter tag
09:36 Dodji: neb: I mean, my idea is that we could interpret the location
expression that represent where the parameter argument is to be found and
normalize the result of that evaluation
09:37 Dodji: we already have such a (partial) interpreter for other purposes,
in the code. We could maybe extend it for this purpose.
09:37 neb: Dodji: that makes sense and honestly, I thought that you were
already doing that for function parameters
09:39 neb: That aspect of calling convention is a VERY important ABI artifact
09:39 Dodji: neb: no, sadly, not yet.
09:39 Dodji: well, "just" handling types has taken quite some time already ;-)
09:40 Dodji: (okay in all fairness we do more than types, but you see what I
mean)
09:40 neb: Well I have a new data set to work on.
09:40 neb: OpenHPC
09:40 neb: However, I just haven't had time to work on it as much as I would
have liked.
09:41 Dodji: neb: yeah, for this, it'd be super cool to have examples of abi
changes due to difference in argument passing, and see how the dwarves look
like in those cases
09:57 mjw: Dodji, that is an interesting issue.
09:58 mjw: Dodji, You might indeed get the calling convention from that.
09:58 mjw: Dodji, But it isn't really what the location descriptors were
designed for.
09:59 mjw: Dodji, They describe the location of values, in this case the
parameters. And you could assume that if the location descriptor is for an
address before the function prologue, then that is how the argument was passed
in.
10:00 mjw: Dodji, If the location is for an address after the function prologue
however...
10:02 mjw: Officially DWARF diverts the calling convention used to the language
specification.
10:04 mjw: It only supports a DW_AT_calling_convention on a DW_TAG_subroutine
with the values DW_CC_normal, DW_CC_program and DW_CC_nocall
10:04 mjw: where normal means the “standard” calling conventions of the target
architecture
10:05 mjw: program is the "main" subroutine (if it has a different calling
convention as in Fortran programs)
10:05 mjw: and nocall means "no idea, just don't call it, we don't know what
the calling convention really is"
10:06 mjw: O, DWARF5 added DW_CC_pass_by_reference and DW_CC_pass_by_value
10:07 mjw: And you can have vendor extensions.
10:08 mjw: Apparently there are some (which elfutils knows nothing about).
DW_CC_GNU_renesas_sh, DW_CC_GNU_borland_fastcall_i386 and DW_CC_GDB_IBM_OpenCL
10:18 mjw: Ah, interesting the new pass by reference and pass by value CC types
are not for subroutines, but for structure type, union type or class type
10:43 neb: mjw: the thing is, this is a very real ABI artifact and calling
convention isn't quite as agreed upon convention in practice as we would like.
10:44 neb: the example that jwakely pointed out is:
https://bugs.llvm.org//show_bug.cgi?id=19668 and
https://bugs.llvm.org//show_bug.cgi?id=23034
10:47 neb: mjw: so even though it isn't what they are designed for since the
problem is that the parameters are in different locations, why should they not
be used that way?
10:47 neb: Yes it is a different use, yes it sort of infers the calling
convention by looking at how the parameter is stored rather than comparing it
to first principles
10:49 neb: however to me that sounds like a better approach because libabigail
wouldn't necessarily have to know anything about the calling conventions for
various platforms and it wouldn't have to in essence arbitrate what is
conforming. It could just point out that the location of these parameters is
different.
10:56 jwakely: yeah, maybe that could work. abigail wouldn't have to have an
opinion on what the correct parameter style is, only care that it's consistent
10:56 mjw: sure, it might work
10:56 mjw: but I wouldn't be surprised if there were weird quirks that might
give false positives.
10:57 mjw: gcc for example gives very different location information for
optimized versus unoptimized code.
10:58 mjw: the problem with unoptimized code is that all arguments are first
put on the stack, and it doesn't bother to emit information for the function
prologue
10:58 mjw: so you cannot use it then
11:00 mjw: e.g. for int foo (int bar)
11:00 mjw: with -O2 -g you'll get:
11:01 mjw: [ 4e] formal_parameter
11:01 mjw: name (string) "bar"
11:01 mjw: decl_file (data1) 1
11:01 mjw: decl_line (data1) 1
11:01 mjw: type (ref4) [ 5c]
11:01 mjw: location (exprloc)
11:01 mjw: [ 0] reg5
11:01 mjw: But with -O0 you'll get:
11:01 mjw: [ 4e] formal_parameter
11:01 mjw: name (string) "bar"
11:01 mjw: decl_file (data1) 1
11:01 mjw: decl_line (data1) 1
11:01 mjw: type (ref4) [ 5d]
11:01 mjw: location (exprloc)
11:01 mjw: [ 0] fbreg -20
11:02 mjw: If you look at the assembly you'll note that the -O0 case is correct
(it is on the stack) only after the prologue...
11:03 mjw: because it does:
11:03 mjw: 0: 55 push %rbp
11:03 mjw: 1: 48 89 e5 mov %rsp,%rbp
11:03 mjw: 4: 89 7d fc mov %edi,-0x4(%rbp)
11:03 mjw: 7: 8b 45 fc mov -0x4(%rbp),%eax
11:03 mjw: a: 5d pop %rbp
11:03 mjw: b: c3 retq
11:03 mjw: While with -O2 it doesn't bother to push all arguments on the stack
and you get:
11:03 mjw: 0: 89 f8 mov %edi,%eax
11:03 mjw: 2: c3 retq
11:04 mjw: This is one of the weird cases where gcc emits better (more precise)
DWARF for optimized code than for unoptimized code.
11:05 neb: that is a rare find. ;-)
11:05 neb: file a bug. ;l-)
11:05 mjw: neb, it is a pity for systemtap
11:05 mjw: normally stap is used on production code and you can easily get the
arguments at the start of a function probe
11:06 mjw: but then people recompile their code without optimization and
suddenly stap gives wrong answers...
11:06 mjw: That is why I know about it.
11:07 mjw: Anyway. I don't want to discourage you from trying to squeeze out as
much information as you can about calling conventions.
11:07 mjw: Just warning that it doesn't always work perfectly.
11:08 neb: However, since what we are talking about is ABI artifacts and not
the challenges of mutating code. In the cases where you have non-static
functions which are being linked together and where the caller only has access
to a header with a declaration, shouldn't the calling convention be explicitly
enough defined that we know where parameters are or is that still hidden away
in the compiler.
11:09 neb: I was always under the impression that within a CU you can do
whatever the hell you want but when a function is exported it has to be pretty
well defined.
11:10 mjw: neb, yes, but it isn't something DWARF explicitly encodes. So to be
sure you'll have to fall back to the architecture/language spec to deduce the
calling convention/how arguments are really passed.
11:10 mjw: Like I said, it might work. But...
11:12 neb: mjw: I guess I hope it works because otherwise I feel like we have a
circular argument, we are trying to detect non-compliance with what we believe
to be an established calling convention
11:13 mjw: Do note that with gcc (but probably not with any other compiler) you
often can also check on the caller side by looking at the DW_TAG_GNU_call_sites
11:13 mjw: neb, I am afraid that is precisely what you will get, a circular
reasoning. But I might be too pessimistic.
11:13 mjw: Don't let me stop you from trying!
11:14 neb: however, our problem is not with GCC, out problem is with other
compilers who don't quite do things right
11:14 mjw: If the result is that gcc gets better at this then we all win :)
11:19 neb: mjw: the part that I'm struggling with deciding from your example
above is "does the fact that the parameter has moved locations from fbreg -20
to reg5 constitute an ABI change
11:30 neb: I'm assuming that the function that you compiled is not static but
this is where my lack of experience shows, I don't see how we could call that
function from another CU without knowing where to stuff the parameters.
11:46 mjw: neb, the issue is NOT an abi change. The issue is that with -O0 -g
gcc doesn't correctly describe the location of the argument (it starts in the
register then gets put on the stack, but gcc pretends it always was on the
stack)
11:47 mjw: But with -O2 -g gcc suddenly decides to be more accurate with its
location description. Helped by the fact that it doesn't even put it on the
stack. But in general gcc -O2 -g produces better location descriptors than with
-O0.
11:47 mjw: There might be a gcc bug about it.
11:50 mjw: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=51358
--
You are receiving this mail because:
You are on the CC list for the bug.
More information about the Libabigail
mailing list