]> git.proxmox.com Git - mirror_edk2.git/blob - UnixPkg/Sec/UnixThunk.c
Integrate patch from Andrew Fish to make it run on OS X.
[mirror_edk2.git] / UnixPkg / Sec / UnixThunk.c
1 /*++
2
3 Copyright (c) 2004 - 2009, Intel Corporation
4 Portions copyright (c) 2008-2009 Apple Inc. All rights reserved.
5 All rights reserved. This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
9
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
12
13 Module Name:
14
15 UnixThunk.c
16
17 Abstract:
18
19 Since the SEC is the only program in our emulation we
20 must use a Tiano mechanism to export APIs to other modules.
21 This is the role of the EFI_UNIX_THUNK_PROTOCOL.
22
23 The mUnixThunkTable exists so that a change to EFI_UNIX_THUNK_PROTOCOL
24 will cause an error in initializing the array if all the member functions
25 are not added. It looks like adding a element to end and not initializing
26 it may cause the table to be initaliized with the members at the end being
27 set to zero. This is bad as jumping to zero will crash.
28
29
30 gUnix is a a public exported global that contains the initialized
31 data.
32
33 --*/
34
35 #include "SecMain.h"
36 #include "Uefi.h"
37 #include "Library/UnixLib.h"
38
39 int settimer_initialized;
40 struct timeval settimer_timeval;
41 void (*settimer_callback)(UINT64 delta);
42
43 void
44 settimer_handler (int sig)
45 {
46 struct timeval timeval;
47 UINT64 delta;
48
49 gettimeofday (&timeval, NULL);
50 delta = ((UINT64)timeval.tv_sec * 1000) + (timeval.tv_usec / 1000)
51 - ((UINT64)settimer_timeval.tv_sec * 1000)
52 - (settimer_timeval.tv_usec / 1000);
53 settimer_timeval = timeval;
54 if (settimer_callback)
55 (*settimer_callback)(delta);
56 }
57
58 VOID
59 SetTimer (UINT64 PeriodMs, VOID (*CallBack)(UINT64 DeltaMs))
60 {
61 struct itimerval timerval;
62 UINT32 remainder;
63
64 if (!settimer_initialized) {
65 struct sigaction act;
66
67 settimer_initialized = 1;
68 act.sa_handler = settimer_handler;
69 act.sa_flags = 0;
70 sigemptyset (&act.sa_mask);
71 if (sigaction (SIGALRM, &act, NULL) != 0) {
72 printf ("SetTimer: sigaction error %s\n", strerror (errno));
73 }
74 if (gettimeofday (&settimer_timeval, NULL) != 0) {
75 printf ("SetTimer: gettimeofday error %s\n", strerror (errno));
76 }
77 }
78 timerval.it_value.tv_sec = DivU64x32(PeriodMs, 1000);
79 DivU64x32Remainder(PeriodMs, 1000, &remainder);
80 timerval.it_value.tv_usec = remainder * 1000;
81 timerval.it_value.tv_sec = DivU64x32(PeriodMs, 1000);
82 timerval.it_interval = timerval.it_value;
83
84 if (setitimer (ITIMER_REAL, &timerval, NULL) != 0) {
85 printf ("SetTimer: setitimer error %s\n", strerror (errno));
86 }
87 settimer_callback = CallBack;
88 }
89
90 void
91 msSleep (unsigned long Milliseconds)
92 {
93 struct timespec ts;
94
95 ts.tv_sec = Milliseconds / 1000;
96 ts.tv_nsec = (Milliseconds % 1000) * 1000000;
97
98 while (nanosleep (&ts, &ts) != 0 && errno == EINTR)
99 ;
100 }
101
102 void
103 GetLocalTime (EFI_TIME *Time)
104 {
105 struct tm *tm;
106 time_t t;
107
108 t = time (NULL);
109 tm = localtime (&t);
110
111 Time->Year = 1900 + tm->tm_year;
112 Time->Month = tm->tm_mon + 1;
113 Time->Day = tm->tm_mday;
114 Time->Hour = tm->tm_hour;
115 Time->Minute = tm->tm_min;
116 Time->Second = tm->tm_sec;
117 Time->Nanosecond = 0;
118 Time->TimeZone = timezone;
119 Time->Daylight = (daylight ? EFI_TIME_ADJUST_DAYLIGHT : 0)
120 | (tm->tm_isdst > 0 ? EFI_TIME_IN_DAYLIGHT : 0);
121 }
122
123 void
124 TzSet (void)
125 {
126 STATIC int done = 0;
127 if (!done) {
128 tzset ();
129 done = 1;
130 }
131 }
132
133 long
134 GetTimeZone(void)
135 {
136 TzSet ();
137 return timezone;
138 }
139
140 int
141 GetDayLight(void)
142 {
143 TzSet ();
144 return daylight;
145 }
146
147 int
148 GetErrno(void)
149 {
150 return errno;
151 }
152
153 #if __APPLE__
154 void GasketmsSleep (unsigned long Milliseconds);
155 void Gasketexit (int status);
156 void GasketSetTimer (UINT64 PeriodMs, VOID (*CallBack)(UINT64 DeltaMs));
157 void GasketGetLocalTime (EFI_TIME *Time);
158 struct tm *Gasketgmtime (const time_t *clock);
159 long GasketGetTimeZone (void);
160 int GasketGetDayLight (void);
161 int Gasketpoll (struct pollfd *pfd, int nfds, int timeout);
162 int Gasketread (int fd, void *buf, int count);
163 int Gasketwrite (int fd, const void *buf, int count);
164 char *Gasketgetenv (const char *name);
165 int Gasketopen (const char *name, int flags, int mode);
166 off_t Gasketlseek (int fd, off_t off, int whence);
167 int Gasketftruncate (int fd, long int len);
168 int Gasketclose (int fd);
169 int Gasketmkdir (const char *pathname, mode_t mode);
170 int Gasketrmdir (const char *pathname);
171 int Gasketunlink (const char *pathname);
172 int GasketGetErrno (void);
173 DIR *Gasketopendir (const char *pathname);
174 void *Gasketrewinddir (DIR *dir);
175 struct dirent *Gasketreaddir (DIR *dir);
176 int Gasketclosedir (DIR *dir);
177 int Gasketstat (const char *path, struct stat *buf);
178 int Gasketstatfs (const char *path, struct statfs *buf);
179 int Gasketrename (const char *oldpath, const char *newpath);
180 time_t Gasketmktime (struct tm *tm);
181 int Gasketfsync (int fd);
182 int Gasketchmod (const char *path, mode_t mode);
183 int Gasketutime (const char *filename, const struct utimbuf *buf);
184 int Gaskettcflush (int fildes, int queue_selector);
185 EFI_STATUS GasketUgaCreate(struct _EFI_UNIX_UGA_IO_PROTOCOL **UgaIo, CONST CHAR16 *Title);
186 void Gasketperror (__const char *__s);
187
188 //
189 // ... is always an int or pointer to device specific data structure
190 //
191 int Gasketioctl (int fd, unsigned long int __request, ...);
192 int Gasketfcntl (int __fd, int __cmd, ...);
193
194 int Gasketcfsetispeed (struct termios *__termios_p, speed_t __speed);
195 int Gasketcfsetospeed (struct termios *__termios_p, speed_t __speed);
196 int Gaskettcgetattr (int __fd, struct termios *__termios_p);
197 int Gaskettcsetattr (int __fd, int __optional_actions, __const struct termios *__termios_p);
198 int Gasketsigaction (int sig, const struct sigaction *act, struct sigaction *oact);
199 int Gasketsetcontext (const ucontext_t *ucp);
200 int Gasketgetcontext (ucontext_t *ucp);
201 int Gasketsigemptyset (sigset_t *set);
202 int Gasketsigaltstack (const stack_t *ss, stack_t *oss);
203
204 RETURN_STATUS
205 GasketUnixPeCoffGetEntryPoint (
206 IN VOID *Pe32Data,
207 IN OUT VOID **EntryPoint
208 );
209
210 VOID
211 GasketUnixPeCoffRelocateImageExtraAction (
212 IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext
213 );
214
215 VOID
216 GasketPeCoffLoaderUnloadImageExtraAction (
217 IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext
218 );
219
220 #endif
221
222 extern EFI_STATUS
223 UgaCreate(struct _EFI_UNIX_UGA_IO_PROTOCOL **UgaIo, CONST CHAR16 *Title);
224
225 EFI_UNIX_THUNK_PROTOCOL mUnixThunkTable = {
226 EFI_UNIX_THUNK_PROTOCOL_SIGNATURE,
227 #ifdef __APPLE__
228 //
229 // Mac OS X requires the stack to be 16-byte aligned for IA-32. So on an OS X build
230 // we add an assembly wrapper that makes sure the stack ges aligned.
231 // This has the nice benfit of being able to run EFI ABI code, like the EFI shell
232 // that is checked in to source control in the OS X version of the emulator
233 //
234 GasketmsSleep, /* Sleep */
235 Gasketexit, /* Exit */
236 GasketSetTimer,
237 GasketGetLocalTime,
238 Gasketgmtime,
239 GasketGetTimeZone,
240 GasketGetDayLight,
241 (UnixPoll)Gasketpoll,
242 (UnixRead)Gasketread,
243 (UnixWrite)Gasketwrite,
244 Gasketgetenv,
245 (UnixOpen)Gasketopen,
246 (UnixSeek)Gasketlseek,
247 (UnixFtruncate)Gasketftruncate,
248 Gasketclose,
249 Gasketmkdir,
250 Gasketrmdir,
251 Gasketunlink,
252 GasketGetErrno,
253 Gasketopendir,
254 (UnixRewindDir)Gasketrewinddir,
255 Gasketreaddir,
256 Gasketclosedir,
257 Gasketstat,
258 Gasketstatfs,
259 Gasketrename,
260 Gasketmktime,
261 Gasketfsync,
262 Gasketchmod,
263 Gasketutime,
264 Gaskettcflush,
265 GasketUgaCreate,
266 Gasketperror,
267 Gasketioctl,
268 Gasketfcntl,
269 Gasketcfsetispeed,
270 Gasketcfsetospeed,
271 Gaskettcgetattr,
272 Gaskettcsetattr,
273
274 dlopen, // Update me with a gasket
275 dlerror, // Update me with a gasket
276 dlsym, // Update me with a gasket
277
278 SecPeCoffGetEntryPoint, // Update me with a gasket
279 SecPeCoffRelocateImageExtraAction, // Update me with a gasket
280 SecPeCoffLoaderUnloadImageExtraAction // Update me with a gasket
281
282 #else
283 msSleep, /* Sleep */
284 exit, /* Exit */
285 SetTimer,
286 GetLocalTime,
287 gmtime,
288 GetTimeZone,
289 GetDayLight,
290 (UnixPoll)poll,
291 (UnixRead)read,
292 (UnixWrite)write,
293 getenv,
294 (UnixOpen)open,
295 (UnixSeek)lseek,
296 (UnixFtruncate)ftruncate,
297 close,
298 mkdir,
299 rmdir,
300 unlink,
301 GetErrno,
302 opendir,
303 rewinddir,
304 readdir,
305 closedir,
306 stat,
307 statfs,
308 rename,
309 mktime,
310 fsync,
311 chmod,
312 utime,
313 tcflush,
314 UgaCreate,
315 perror,
316 ioctl,
317 fcntl,
318 cfsetispeed,
319 cfsetospeed,
320 tcgetattr,
321 tcsetattr,
322 dlopen,
323 dlerror,
324 dlsym,
325 SecPeCoffGetEntryPoint,
326 SecPeCoffRelocateImageExtraAction,
327 SecPeCoffLoaderUnloadImageExtraAction
328 #endif
329 };
330
331
332 EFI_UNIX_THUNK_PROTOCOL *gUnix = &mUnixThunkTable;