Do not export AT_CLKTCK when emulating Linux kernel prior

to 2.4.0, as it has appeared in the 2.4.0-rc7 first time.
Being exported, AT_CLKTCK is returned by sysconf(_SC_CLK_TCK),
glibc falls back to the hard-coded CLK_TCK value when aux entry
is not present.

Glibc versions prior to 2.2.1 always use hard-coded CLK_TCK value.

For older applications/libc's which depends on hard-coded CLK_TCK
value user should set compat.linux.osrelease less than 2.4.0.

Approved by:	kib (mentor)
This commit is contained in:
dchagin 2009-05-10 18:43:43 +00:00
parent e4e6bf246f
commit 51f122997d
4 changed files with 36 additions and 3 deletions

View File

@ -261,7 +261,17 @@ elf_linux_fixup(register_t **stack_base, struct image_params *imgp)
pos = base + (imgp->args->argc + imgp->args->envc + 2);
AUXARGS_ENTRY_32(pos, LINUX_AT_HWCAP, cpu_feature);
AUXARGS_ENTRY_32(pos, LINUX_AT_CLKTCK, stclohz);
/*
* Do not export AT_CLKTCK when emulating Linux kernel prior to 2.4.0,
* as it has appeared in the 2.4.0-rc7 first time.
* Being exported, AT_CLKTCK is returned by sysconf(_SC_CLK_TCK),
* glibc falls back to the hard-coded CLK_TCK value when aux entry
* is not present.
* Also see linux_times() implementation.
*/
if (linux_kernver(curthread) >= LINUX_KERNVER_2004000)
AUXARGS_ENTRY_32(pos, LINUX_AT_CLKTCK, stclohz);
AUXARGS_ENTRY_32(pos, AT_PHDR, args->phdr);
AUXARGS_ENTRY_32(pos, AT_PHENT, args->phent);
AUXARGS_ENTRY_32(pos, AT_PHNUM, args->phnum);

View File

@ -45,6 +45,7 @@ int linux_set_oss_version(struct thread *td, int oss_version);
int linux_kernver(struct thread *td);
#define LINUX_KERNVER_2004000 2004000
#define LINUX_KERNVER_2006000 2006000
#define linux_use26(t) (linux_kernver(t) >= LINUX_KERNVER_2006000)

View File

@ -661,7 +661,19 @@ struct l_times_argv {
l_clock_t tms_cstime;
};
#define CONVTCK(r) (r.tv_sec * stclohz + r.tv_usec / (1000000 / stclohz))
/*
* Glibc versions prior to 2.2.1 always use hard-coded CLK_TCK value.
* Since 2.2.1 Glibc uses value exported from kernel via AT_CLKTCK
* auxiliary vector entry.
*/
#define CLK_TCK 100
#define CONVOTCK(r) (r.tv_sec * CLK_TCK + r.tv_usec / (1000000 / CLK_TCK))
#define CONVNTCK(r) (r.tv_sec * stclohz + r.tv_usec / (1000000 / stclohz))
#define CONVTCK(r) (linux_kernver(td) >= LINUX_KERNVER_2004000 ? \
CONVNTCK(r) : CONVOTCK(r))
int
linux_times(struct thread *td, struct linux_times_args *args)

View File

@ -255,7 +255,17 @@ elf_linux_fixup(register_t **stack_base, struct image_params *imgp)
pos = *stack_base + (imgp->args->argc + imgp->args->envc + 2);
AUXARGS_ENTRY(pos, LINUX_AT_HWCAP, cpu_feature);
AUXARGS_ENTRY(pos, LINUX_AT_CLKTCK, stclohz);
/*
* Do not export AT_CLKTCK when emulating Linux kernel prior to 2.4.0,
* as it has appeared in the 2.4.0-rc7 first time.
* Being exported, AT_CLKTCK is returned by sysconf(_SC_CLK_TCK),
* glibc falls back to the hard-coded CLK_TCK value when aux entry
* is not present.
* Also see linux_times() implementation.
*/
if (linux_kernver(curthread) >= LINUX_KERNVER_2004000)
AUXARGS_ENTRY(pos, LINUX_AT_CLKTCK, stclohz);
AUXARGS_ENTRY(pos, AT_PHDR, args->phdr);
AUXARGS_ENTRY(pos, AT_PHENT, args->phent);
AUXARGS_ENTRY(pos, AT_PHNUM, args->phnum);