clang generated code sometimes confuses fbt

Andriy Gapon avg at FreeBSD.org
Sat Mar 2 17:36:12 UTC 2013


I observe the following problem.

There are two tiny wrapper functions around a larger implementation function:
int
bpobj_iterate(bpobj_t *bpo, bpobj_itor_t func, void *arg, dmu_tx_t *tx)
{
        return (bpobj_iterate_impl(bpo, func, arg, tx, B_TRUE));
}
int
bpobj_iterate_nofree(bpobj_t *bpo, bpobj_itor_t func, void *arg, dmu_tx_t *tx)
{
        return (bpobj_iterate_impl(bpo, func, arg, tx, B_FALSE));
}

On a clang compiled system:
$ dtrace -l | fgrep bpobj_iterate
 1483        fbt            kernel                bpobj_iterate_impl entry
 1484        fbt            kernel                bpobj_iterate_impl return

On a gcc compiled system:
dtrace -l | fgrep bpobj_iterate
  647        fbt            kernel                bpobj_iterate_impl entry
  648        fbt            kernel                bpobj_iterate_impl return
20656        fbt            kernel                     bpobj_iterate entry
20657        fbt            kernel                     bpobj_iterate return
28426        fbt            kernel              bpobj_iterate_nofree entry
28427        fbt            kernel              bpobj_iterate_nofree return

Examination reveals why that is so.
clang:
Dump of assembler code for function bpobj_iterate:
0xffffffff802d5a90 <bpobj_iterate+0>:   mov    $0x1,%r8d
0xffffffff802d5a96 <bpobj_iterate+6>:   jmp    0xffffffff802d5aa0
<bpobj_iterate_impl>

gcc:
Dump of assembler code for function bpobj_iterate:
0xffffffff802d3f43 <bpobj_iterate+0>:   push   %rbp
0xffffffff802d3f44 <bpobj_iterate+1>:   mov    %rsp,%rbp
0xffffffff802d3f47 <bpobj_iterate+4>:   mov    $0x1,%r8d
0xffffffff802d3f4d <bpobj_iterate+10>:  callq  0xffffffff802d3787
<bpobj_iterate_impl>
0xffffffff802d3f52 <bpobj_iterate+15>:  pop    %rbp
0xffffffff802d3f53 <bpobj_iterate+16>:  retq

So quite obviously fbt can not really entry/return points for the clang function.

This is not a big problem on its own, of course, but here is a bad twist.
On the clang system:
$ ctfdump -f /boot/kernel/kernel | fgrep bpobj_iterate
  [8975] FUNC (bpobj_iterate) returns: 24 args: (2601, 4824, 34, 2221)
  [13093] FUNC (bpobj_iterate_nofree) returns: 24 args: (2601, 4824, 34, 2221)

Now that's the problem: fbt sees only bpobj_iterate_impl, but CTF data is
generated/present only for bpobj_iterate and bpobj_iterate_nofree.

On the gcc system:
ctfdump -f /boot/kernel/kernel | fgrep bpobj_iterate
  [323] FUNC (bpobj_iterate_impl) returns: 1 args: (5153, 5661, 6, 5078, 1350)
  [10439] FUNC (bpobj_iterate) returns: 1 args: (5153, 5661, 6, 5078)
  [14377] FUNC (bpobj_iterate_nofree) returns: 1 args: (5153, 5661, 6, 5078)

To summarize: I would be glad of either clang generated code was "fbt-friendly"
or if ctf information was generated for bpobj_iterate_impl.  Either is perfect
for me.

Now, I am not quite sure why ctfconvert skips bpobj_iterate_impl in the
clang-generated code.  Seems like some sort of a bug in ctfconvert.

-- 
Andriy Gapon


More information about the freebsd-hackers mailing list