https://gcc.gnu.org/bugzilla/show_bug.cgi?id=84908

--- Comment #8 from Jason Vas Dias <jason.vas.dias at gmail dot com> ---
Thanks for the clarification, and I hope the kernel
developers stop compiling the mainline vDSO with
-mindirect-branch=thunk-extern -mindirect-branch-register 
.

But there are still a few things I am trying to figure out :

 o Why is the thunk entry reference & relocation inserted
   for 6 switch clauses and not for 5 ?


 o So do I understand correctly: 

    __x86_indirect_thunk_rax

   is resolved and jumped to save %rax , jump to the address in %rcx, 
   and then restore %rax, and return ?

   it is normally 
    A) generated for libraries / executable as required or 
    B) is in libgcc ?

   If (A), then what triggers it and why is it not being generated for the
vDSO?
   If (B), then where is the code in libgcc ? I can't find it.


I'd also like more details on why it is wrong to compile the vDSO with these 
flags - it does work, and yes causes compilation problems like this one which
can be worked around by declaring all 'notrace static inline' entry points
in vclock_gettime.c to have the function attributes:
   static inline 
   __attribute__((
     indirect_branch("keep"),
     function_return("keep")
   ))
   int do_monotonic_raw( int clock, struct timespec *ts );
which effectively disables the effect of 
   -mindirect-branch=thunk-extern -mindirect-branch-register
for these functions ; also __vdso_clock_gettime itself MUST
be then declared:
   __attribute__((
     indirect_branch("keep"),
     function_return("keep")
   )) 
   int __vdso_clock_gettime ( ... ) { ...

But does it cause any other issues ?

I did investigate changing the switch in __vdso_clock_gettime
to :

#define _GTOD_LABEL_PREFIX_ _vcg_
#define _SYMCAT_(_S1_,_S2_) _S1_##_S2_
#define _GTOD_CLK_LABEL_(_CLK_) _SYMCAT_(_GTOD_LABEL_PREFIX_,_CLK_)

notrace int __vdso_clock_gettime(clockid_t clock, struct timespec *ts)
{
        static const void * clk_jmp_tbl[ MAX_CLOCKS ]   = {
                [ CLOCK_REALTIME  ]             =
&&_GTOD_CLK_LABEL_(CLOCK_REALTIME) ,
                [ CLOCK_MONOTONIC ]             =
&&_GTOD_CLK_LABEL_(CLOCK_MONOTONIC) ,
                [ CLOCK_PROCESS_CPUTIME_ID ]    = &&fallback ,
                [ CLOCK_THREAD_CPUTIME_ID  ]    = &&fallback ,
                [ CLOCK_MONOTONIC_RAW      ]    =
&&_GTOD_CLK_LABEL_(CLOCK_MONOTONIC_RAW) ,
                [ CLOCK_REALTIME_COARSE    ]    =
&&_GTOD_CLK_LABEL_(CLOCK_REALTIME_COARSE) ,
                [ CLOCK_MONOTONIC_COARSE   ]    =
&&_GTOD_CLK_LABEL_(CLOCK_MONOTONIC_COARSE) ,
                [ CLOCK_BOOTTIME           ]    = &&fallback ,
                [ CLOCK_BOOTTIME_ALARM     ]    = &&fallback ,
                [ CLOCK_SGI_CYCLE          ]    = &&fallback ,
                [ CLOCK_TAI                ]    = &&fallback , // unused clocks
                [ 12                       ]    = &&not_supported ,
                [ 13                       ]    = &&not_supported ,
                [ 14                       ]    = &&not_supported ,
                [ 15                       ]    = &&not_supported
        };

        goto *clk_jmp_tbl [ clock & 0xf ] ;

 _GTOD_CLK_LABEL_(CLOCK_REALTIME)        :
        if (do_realtime(ts) == VCLOCK_NONE)
                goto fallback;
        goto return_ok;
 _GTOD_CLK_LABEL_(CLOCK_MONOTONIC)       :
        if (do_monotonic(ts) == VCLOCK_NONE)
                goto fallback;
        goto return_ok;
 _GTOD_CLK_LABEL_(CLOCK_MONOTONIC_RAW)   :
        if (do_monotonic_raw(ts) == VCLOCK_NONE)
                goto fallback;
        goto return_ok;
 _GTOD_CLK_LABEL_(CLOCK_REALTIME_COARSE) :
        do_realtime_coarse(ts);
        goto return_ok;
 _GTOD_CLK_LABEL_(CLOCK_MONOTONIC_COARSE):
        do_monotonic_coarse(ts);
        goto return_ok;
 return_ok:
        return 0;
 not_supported:
        return -1;
 fallback:
        return vdso_fallback_gettime(clock, ts);
}

Results in 16 dynamic relocations,

shown in objdump -R arch/x86/entry/vdso/vdso64.so.dbg output:

DYNAMIC RELOCATION RECORDS
OFFSET           TYPE              VALUE
00000000000004a0 R_X86_64_RELATIVE  *ABS*+0x0000000000000c49
...
000000000000518 R_X86_64_RELATIVE  *ABS*+0x0000000000000b31

what's the problem with dyn relocs ?


I can't understand why GCC decides to generate relocations 
here - it knows all the information before hand - why 
can't it insert code to compute 
( ( LOAD_ADDRESS_OF(__vdso_clock_gettime) == %pc at entry) + label_offset )
and populate the clk_jmp_table in an initializer in the
above version of the function rather than generate 
relocations ? 

Thanks & Best Regards,
Jason

Reply via email to