source: trunk/src/peldr/helpers.c@ 21942

Last change on this file since 21942 was 21942, checked in by dmik, 14 years ago

Use custom startup code for PE loader.

This allows to grab the lowest memory address before any DLL
(including the C library) kicks in and reserves memory for its own
purposes. This fixes #54.

File size: 7.4 KB
Line 
1/** @file
2 *
3 * Helper functions for the PE loader.
4 *
5 * These are needed since we don't link to LIBC.
6 *
7 * Project Odin Software License can be found in LICENSE.TXT
8 */
9
10#include "helpers.h"
11
12#ifndef NULL
13#define NULL 0
14#endif
15
16void *memcpy(void *p1, const void *p2, int n)
17{
18 char *p = (char *)p1;
19 while (n)
20 {
21 *p++ = *(char *)(p2++);
22 n--;
23 }
24 return p1;
25}
26
27char *strcpy(char *s1, const char *s2)
28{
29 char *s = s1;
30 while (*s2)
31 *s++ = *s2++;
32 *s = '\0';
33 return s1;
34}
35
36int strlen(const char *s)
37{
38 const char *s2 = s;
39 while (*s2)
40 s2++;
41 return s2 - s;
42}
43
44char *strcat(char *s1, const char *s2)
45{
46 char *s = s1;
47 while (*s)
48 s++;
49 strcpy(s, s2);
50 return s1;
51}
52
53int str_starts_with(const char *s1, const char *s2)
54{
55 while (*s1 && *s2 && *s1 == *s2)
56 {
57 s1++;
58 s2++;
59 }
60 return !*s2;
61}
62
63const char *str_skip_char(const char *s, int c)
64{
65 while (*s && *s == c)
66 s++;
67 return s;
68}
69
70const char *str_find_char(const char *s, int c)
71{
72 while (*s && *s != c)
73 s++;
74 return s;
75}
76
77//
78// BEGIN: taken from _ras.cpp
79//
80
81void ulong2string (unsigned long number, char *string, int n, int base)
82{
83 static const char *digits = "0123456789ABCDEF";
84
85 unsigned long tmp = number;
86 char *s = string;
87 int len = 0;
88 int l = 0;
89 int i;
90
91 if (n <= 0)
92 {
93 return;
94 }
95
96 if (tmp == 0)
97 {
98 s[l++] = digits[0];
99 }
100
101 while (tmp != 0)
102 {
103 if (l >= n)
104 {
105 break;
106 }
107 s[l++] = digits[tmp%base];
108 len++;
109 tmp /= base;
110 }
111 if (l < n)
112 {
113 s[l++] = '\0';
114 }
115
116 s = string;
117
118 for (i = 0; i < len/2; i++)
119 {
120 tmp = s[i];
121 s[i] = s[len - i - 1];
122 s[len - i - 1] = tmp;
123 }
124
125 return;
126}
127
128void long2string (long number, char *string, int n, int base)
129{
130 if (n <= 0)
131 {
132 return;
133 }
134
135 if (number < 0)
136 {
137 *string++ = '-';
138 number = -number;
139 n--;
140 }
141
142 ulong2string (number, string, n, base);
143}
144
145int string2ulong (const char *string, char **pstring2, unsigned long *pvalue, int base)
146{
147 unsigned long value = 0;
148 int sign = 1;
149
150 const char *p = string;
151
152 if (p[0] == '-')
153 {
154 sign = -1;
155 p++;
156 }
157
158 if (base == 0)
159 {
160 if (p[0] == 0 && (p[1] == 'x' || p[1] == 'X'))
161 {
162 base = 16;
163 p += 2;
164 }
165 else if (p[0] == 0)
166 {
167 base = 8;
168 p += 1;
169 }
170 else
171 {
172 base = 10;
173 }
174 }
175
176 while (*p)
177 {
178 int digit = 0;
179
180 if ('0' <= *p && *p <= '9')
181 {
182 digit = *p - '0';
183 }
184 else if ('a' <= *p && *p <= 'f')
185 {
186 digit = *p - 'a' + 0xa;
187 }
188 else if ('A' <= *p && *p <= 'F')
189 {
190 digit = *p - 'A' + 0xa;
191 }
192 else
193 {
194 break;
195 }
196
197 if (digit >= base)
198 {
199 break;
200 }
201
202 value = value*base + digit;
203
204 p++;
205 }
206
207 if (pstring2)
208 {
209 *pstring2 = (char *)p;
210 }
211
212 *pvalue = sign*value;
213
214 return 1;
215}
216
217int vsnprintf(char *buf, int n, const char *fmt, va_list args)
218{
219 int count = 0;
220 char *s = (char *)fmt;
221 char *d = buf;
222
223 if (n <= 0)
224 {
225 return 0;
226 }
227
228 n--;
229
230 while (*s && count < n)
231 {
232 char tmpstr[16];
233
234 char *str = NULL;
235
236 int width = 0;
237 int precision = 0;
238
239 if (*s == '%')
240 {
241 s++;
242
243 if ('0' <= *s && *s <= '9' || *s == '-')
244 {
245 char setprec = (*s == '0');
246 string2ulong (s, &s, (unsigned long *)&width, 10);
247 if (setprec)
248 {
249 precision = width;
250 }
251 }
252
253 if (*s == '.')
254 {
255 s++;
256 string2ulong (s, &s, (unsigned long *)&precision, 10);
257 }
258
259 if (*s == 's')
260 {
261 str = va_arg(args, char *);
262 s++;
263 precision = 0;
264 }
265 else if (*s == 'c')
266 {
267 tmpstr[0] = va_arg(args, int);
268 tmpstr[1] = 0;
269 str = &tmpstr[0];
270 s++;
271 precision = 0;
272 }
273 else if (*s == 'p' || *s == 'P')
274 {
275 int num = va_arg(args, int);
276
277 ulong2string (num, tmpstr, sizeof (tmpstr), 16);
278
279 str = &tmpstr[0];
280 s++;
281 width = 8;
282 precision = 8;
283 }
284 else
285 {
286 if (*s == 'l')
287 {
288 s++;
289 }
290
291 if (*s == 'd' || *s == 'i')
292 {
293 int num = va_arg(args, int);
294
295 long2string (num, tmpstr, sizeof (tmpstr), 10);
296
297 str = &tmpstr[0];
298 s++;
299 }
300 else if (*s == 'u')
301 {
302 int num = va_arg(args, int);
303
304 ulong2string (num, tmpstr, sizeof (tmpstr), 10);
305
306 str = &tmpstr[0];
307 s++;
308 }
309 else if (*s == 'x' || *s == 'X')
310 {
311 int num = va_arg(args, int);
312
313 ulong2string (num, tmpstr, sizeof (tmpstr), 16);
314
315 str = &tmpstr[0];
316 s++;
317 }
318 }
319 }
320
321 if (str != NULL)
322 {
323 int i;
324 char numstr[16];
325 int len = strlen (str);
326 int leftalign = 0;
327
328 if (width < 0)
329 {
330 width = -width;
331 leftalign = 1;
332 }
333
334 if (precision)
335 {
336 i = 0;
337 while (precision > len)
338 {
339 numstr[i++] = '0';
340 precision--;
341 }
342
343 memcpy (&numstr[i], str, len);
344
345 str = &numstr[0];
346 len += i;
347 }
348
349 if (len < width && !leftalign)
350 {
351 while (len < width && count < n)
352 {
353 *d++ = ' ';
354 width--;
355 count++;
356 }
357
358 if (count >= n)
359 {
360 break;
361 }
362 }
363
364 i = 0;
365 while (i < len && count < n)
366 {
367 *d++ = str[i++];
368 count++;
369 }
370
371 if (count >= n)
372 {
373 break;
374 }
375
376 if (len < width && leftalign)
377 {
378 while (len < width && count < n)
379 {
380 *d++ = ' ';
381 width--;
382 count++;
383 }
384
385 if (count >= n)
386 {
387 break;
388 }
389 }
390 }
391 else
392 {
393 *d++ = *s++;
394 count++;
395 }
396 }
397
398 *d = '\0';
399
400 return count + 1;
401}
402
403int snprintf(char *buf, int n, const char *fmt, ...)
404{
405 va_list args;
406
407 int rc = 0;
408
409 va_start (args, fmt);
410
411 rc = vsnprintf (buf, n, fmt, args);
412
413 va_end (args);
414
415 return rc;
416}
417
418//
419// END: taken from _ras.cpp
420//
Note: See TracBrowser for help on using the repository browser.