@@ -102,6 +102,27 @@ static void rt_vdso_counter_to_timespec(rt_uint64_t counter_value,
102102 ts -> tv_nsec = monotonic_ns % RT_VDSO_NSEC_PER_SEC ;
103103}
104104
105+ static rt_uint64_t rt_vdso_read_arch_counter (void )
106+ {
107+ rt_uint64_t counter ;
108+
109+ #if defined(__aarch64__ )
110+ __asm__ volatile ("mrs %0, CNTVCT_EL0" : "=r" (counter ));
111+ #elif defined(__arm__ )
112+ rt_uint32_t lo ;
113+ rt_uint32_t hi ;
114+
115+ __asm__ volatile ("mrrc p15, 1, %0, %1, c14" : "=r" (lo ), "=r" (hi ));
116+ counter = ((rt_uint64_t )hi << 32 ) | lo ;
117+ #elif defined(__riscv )
118+ __asm__ volatile ("rdtime %0" : "=r" (counter ));
119+ #else
120+ counter = rt_clock_time_get_counter ();
121+ #endif
122+
123+ return counter ;
124+ }
125+
105126static struct timespec rt_vdso_timespec_subtract (const struct timespec * lhs ,
106127 const struct timespec * rhs )
107128{
@@ -130,14 +151,18 @@ static int rt_vdso_read_monotonic_snapshot(struct timespec *monotonic_time,
130151 rt_uint64_t * counter_value ,
131152 rt_uint64_t * counter_freq )
132153{
133- * counter_value = rt_clock_time_get_counter ();
154+ rt_uint64_t monotonic_counter ;
155+
156+ monotonic_counter = rt_clock_time_get_counter ();
134157 * counter_freq = rt_clock_time_get_freq ();
135158 if (* counter_freq == 0 )
136159 {
137160 return - RT_ERROR ;
138161 }
139162
140- rt_vdso_counter_to_timespec (* counter_value , monotonic_time );
163+ /* User vDSO computes deltas from the raw architecture counter. */
164+ * counter_value = rt_vdso_read_arch_counter ();
165+ rt_vdso_counter_to_timespec (monotonic_counter , monotonic_time );
141166
142167 return RT_EOK ;
143168}
@@ -319,46 +344,99 @@ void rt_vdso_sync_clock_data(void)
319344 rt_hw_spin_unlock (& rt_vdso_data_page_lock );
320345}
321346
322- static int rt_vdso_validate_image ( void )
347+ static int rt_vdso_validate_elf_header ( const void * image )
323348{
324- const Elf64_Ehdr * ehdr =
325- (const Elf64_Ehdr * )rt_vdso_binaries [RT_VDSO_BINARY_COMMON ].image_start ;
349+ const unsigned char * ident = (const unsigned char * )image ;
326350
327- rt_memset (rt_vdso_data_page_store .raw , 0 , sizeof (rt_vdso_data_page_store .raw ));
328- rt_vdso_realtime_offset_ready = RT_FALSE ;
329- rt_memset (& rt_vdso_realtime_offset , 0 , sizeof (rt_vdso_realtime_offset ));
351+ #if defined(__aarch64__ )
352+ const Elf64_Ehdr * ehdr = (const Elf64_Ehdr * )image ;
330353
331- if (rt_memcmp (rt_vdso_binaries [RT_VDSO_BINARY_COMMON ].image_start ,
332- RT_VDSO_IMAGE_ELF_MAGIC , RT_VDSO_IMAGE_ELF_MAGIC_LEN ))
354+ if (ident [EI_CLASS ] != ELFCLASS64 )
333355 {
334- LOG_E ("vDSO is not a valid ELF object!" );
335- rt_vdso_runtime_status = - RT_ERROR ;
356+ LOG_E ("vDSO ELF class mismatch: expect ELF64" );
336357 return - RT_ERROR ;
337358 }
338359
339- if (ehdr -> e_ident [ EI_CLASS ] != ELFCLASS64 || ehdr -> e_type != ET_DYN )
360+ if (ehdr -> e_type != ET_DYN )
340361 {
341- LOG_E ("vDSO ELF class/type mismatch!" );
342- rt_vdso_runtime_status = - RT_ERROR ;
362+ LOG_E ("vDSO ELF type mismatch!" );
343363 return - RT_ERROR ;
344364 }
345365
346- #if defined(__aarch64__ )
347366 if (ehdr -> e_machine != EM_AARCH64 )
348367 {
349368 LOG_E ("vDSO machine mismatch: expect AArch64" );
350- rt_vdso_runtime_status = - RT_ERROR ;
369+ return - RT_ERROR ;
370+ }
371+ #elif defined(__arm__ )
372+ const Elf32_Ehdr * ehdr = (const Elf32_Ehdr * )image ;
373+
374+ if (ident [EI_CLASS ] != ELFCLASS32 )
375+ {
376+ LOG_E ("vDSO ELF class mismatch: expect ELF32" );
377+ return - RT_ERROR ;
378+ }
379+
380+ if (ehdr -> e_type != ET_DYN )
381+ {
382+ LOG_E ("vDSO ELF type mismatch!" );
383+ return - RT_ERROR ;
384+ }
385+
386+ if (ehdr -> e_machine != EM_ARM )
387+ {
388+ LOG_E ("vDSO machine mismatch: expect ARM" );
351389 return - RT_ERROR ;
352390 }
353391#elif defined(__riscv )
392+ const Elf64_Ehdr * ehdr = (const Elf64_Ehdr * )image ;
393+
394+ if (ident [EI_CLASS ] != ELFCLASS64 )
395+ {
396+ LOG_E ("vDSO ELF class mismatch: expect ELF64" );
397+ return - RT_ERROR ;
398+ }
399+
400+ if (ehdr -> e_type != ET_DYN )
401+ {
402+ LOG_E ("vDSO ELF type mismatch!" );
403+ return - RT_ERROR ;
404+ }
405+
354406 if (ehdr -> e_machine != EM_RISCV )
355407 {
356408 LOG_E ("vDSO machine mismatch: expect RISC-V" );
357- rt_vdso_runtime_status = - RT_ERROR ;
358409 return - RT_ERROR ;
359410 }
411+ #else
412+ LOG_E ("vDSO unsupported architecture!" );
413+ return - RT_ERROR ;
360414#endif
361415
416+ return RT_EOK ;
417+ }
418+
419+ static int rt_vdso_validate_image (void )
420+ {
421+ const void * image = rt_vdso_binaries [RT_VDSO_BINARY_COMMON ].image_start ;
422+
423+ rt_memset (rt_vdso_data_page_store .raw , 0 , sizeof (rt_vdso_data_page_store .raw ));
424+ rt_vdso_realtime_offset_ready = RT_FALSE ;
425+ rt_memset (& rt_vdso_realtime_offset , 0 , sizeof (rt_vdso_realtime_offset ));
426+
427+ if (rt_memcmp (image , RT_VDSO_IMAGE_ELF_MAGIC , RT_VDSO_IMAGE_ELF_MAGIC_LEN ))
428+ {
429+ LOG_E ("vDSO is not a valid ELF object!" );
430+ rt_vdso_runtime_status = - RT_ERROR ;
431+ return - RT_ERROR ;
432+ }
433+
434+ if (rt_vdso_validate_elf_header (image ) != RT_EOK )
435+ {
436+ rt_vdso_runtime_status = - RT_ERROR ;
437+ return - RT_ERROR ;
438+ }
439+
362440 rt_vdso_binaries [RT_VDSO_BINARY_COMMON ].page_count =
363441 (rt_vdso_binaries [RT_VDSO_BINARY_COMMON ].image_end -
364442 rt_vdso_binaries [RT_VDSO_BINARY_COMMON ].image_start ) >>
0 commit comments