21 * Copyright (c) 2010, Oracle and/or it's affiliates. All rights reserved. |
21 * Copyright (c) 2010, Oracle and/or it's affiliates. All rights reserved. |
22 */ |
22 */ |
23 |
23 |
24 /* |
24 /* |
25 * This compiles to a module that can be preloaded during a build. If this |
25 * This compiles to a module that can be preloaded during a build. If this |
26 * is preloaded, it interposes on time(2) and returns a constant value when |
26 * is preloaded, it interposes on time(2), gettimeofday(3C), and |
27 * the execname matches one of the desired "programs" and TIME_CONSTANT |
27 * clock_gethrtime(3C) and returns a constant number of seconds since epoch |
|
28 * when the execname matches one of the desired "programs" and TIME_CONSTANT |
28 * contains an integer value to be returned. |
29 * contains an integer value to be returned. |
29 */ |
30 */ |
30 |
31 |
31 #include <stdlib.h> |
32 #include <stdlib.h> |
32 #include <ucontext.h> |
33 #include <ucontext.h> |
33 #include <dlfcn.h> |
34 #include <dlfcn.h> |
34 #include <strings.h> |
35 #include <strings.h> |
|
36 #include <time.h> |
35 |
37 |
36 /* The list of programs that we want to use a constant time. */ |
38 /* The list of programs that we want to use a constant time. */ |
37 static char *programs[] = { "date", "cpp", "cc1", "perl", NULL }; |
39 static char *programs[] = { "autogen", "bash", "cpp", "cc1", "date", "doxygen", |
|
40 "erl", "javadoc", "ksh", "ksh93", "ld", "perl", "perl5.8.4", "perl5.10", |
|
41 "ruby", "sh", NULL }; |
38 |
42 |
39 static int |
43 static int |
40 stack_info(uintptr_t pc, int signo, void *arg) |
44 stack_info(uintptr_t pc, int signo, void *arg) |
41 { |
45 { |
42 Dl_info info; |
46 Dl_info info; |
43 void *sym; |
47 void *sym; |
44 |
48 |
45 if (dladdr1((void *)pc, &info, &sym, RTLD_DL_SYMENT) != NULL) { |
49 if (dladdr1((void *)pc, &info, &sym, RTLD_DL_SYMENT) != NULL) { |
46 *(char **)arg = (char *)info.dli_fname; |
50 if (strstr(info.dli_fname, ".so") == NULL) |
|
51 *(char **)arg = (char *)info.dli_fname; |
47 } |
52 } |
48 |
53 |
49 return (0); |
54 return (0); |
50 } |
55 } |
51 |
56 |
70 |
75 |
71 return (execname); |
76 return (execname); |
72 } |
77 } |
73 |
78 |
74 static time_t |
79 static time_t |
75 intercept() |
80 time_constant() |
76 { |
81 { |
77 char *execname = my_execname(); |
82 char *execname = my_execname(); |
78 time_t result = -1; |
83 time_t result = -1; |
79 |
84 |
80 if (execname != NULL) { |
85 if (execname != NULL) { |
81 int i; |
86 int i; |
82 |
87 |
83 for (i = 0; programs[i] != NULL; i++) |
88 for (i = 0; programs[i] != NULL; i++) |
84 if (strcmp(execname, programs[i]) == 0) { |
89 if (strcmp(execname, programs[i]) == 0) { |
85 static char *time_constant; |
90 static char *time_string; |
86 |
91 |
87 if (time_constant == NULL) |
92 if (time_string == NULL) |
88 time_constant = getenv("TIME_CONSTANT"); |
93 time_string = getenv("TIME_CONSTANT"); |
89 |
94 |
90 if (time_constant != NULL) |
95 if (time_string != NULL) |
91 result = atoll(time_constant); |
96 result = atoll(time_string); |
92 |
97 |
93 break; |
98 break; |
94 } |
99 } |
95 } |
100 } |
96 |
101 |
112 } else if (ptr != NULL) |
117 } else if (ptr != NULL) |
113 *ptr = result; |
118 *ptr = result; |
114 |
119 |
115 return (result); |
120 return (result); |
116 } |
121 } |
|
122 |
|
123 int |
|
124 gettimeofday(struct timeval *tp, void *tzp) |
|
125 { |
|
126 static int (*fptr)(struct timeval *, void *); |
|
127 int result = -1; |
|
128 |
|
129 if (fptr == NULL) |
|
130 fptr = (int (*)(struct timeval *, void *))dlsym(RTLD_NEXT, |
|
131 "gettimeofday"); |
|
132 |
|
133 if ((result = (fptr)(tp, tzp)) == 0) { |
|
134 time_t curtime = time_constant(); |
|
135 |
|
136 if (curtime != (time_t)-1) |
|
137 tp->tv_sec = curtime; |
|
138 } |
|
139 |
|
140 return (result); |
|
141 } |
|
142 |
|
143 int |
|
144 clock_gettime(clockid_t clock_id, struct timespec *tp) |
|
145 { |
|
146 static int (*fptr)(clockid_t, struct timespec *); |
|
147 int result = -1; |
|
148 |
|
149 if (fptr == NULL) |
|
150 fptr = (int (*)(clockid_t, struct timespec *))dlsym(RTLD_NEXT, |
|
151 "clock_gettime"); |
|
152 |
|
153 if ((result = (fptr)(clock_id, tp)) == 0) { |
|
154 time_t curtime = time_constant(); |
|
155 |
|
156 if (curtime != (time_t)-1) |
|
157 tp->tv_sec = curtime; |
|
158 } |
|
159 |
|
160 return (result); |
|
161 } |