source: trunk/kLdr/kLdrHlp.h@ 2861

Last change on this file since 2861 was 2861, checked in by bird, 19 years ago

Put the PE module interpreter thru the wringer and learnt how much the window file mapping API sucks.

  • Property svn:keywords set to Id
File size: 8.0 KB
RevLine 
[2826]1/* $Id: kLdrHlp.h 2861 2006-11-10 03:04:42Z bird $ */
[2821]2/** @file
3 *
4 * kLdr - The Dynamic Loader, Helper Functions.
5 *
6 * Copyright (c) 2006 knut st. osmundsen <bird@anduin.net>
7 *
8 *
9 * This file is part of kLdr.
10 *
11 * kLdr is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * kLdr is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with kLdr; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 *
25 */
26
27
28#ifndef __kLdrHlp_h__
29#define __kLdrHlp_h__
30
[2825]31/** @defgroup grp_kLdrHlp kLdrHlp - Helper Functions
32 * @internal
33 * @{ */
[2827]34
[2824]35/** Get the minimum of two values. */
[2861]36#define KLDR_MIN(a, b) ((a) <= (b) ? (a) : (b))
[2846]37/** Get the maximum of two values. */
[2861]38#define KLDR_MAX(a, b) ((a) >= (b) ? (a) : (b))
[2827]39/** Calculate the offset of a structure member. */
[2858]40#define KLDR_OFFSETOF(strct, memb) ( (size_t)( &((strct *)0)->memb ) )
[2825]41/** Align a size_t value. */
42#define KLDR_ALIGN_Z(val, align) ( ((val) + ((align) - 1)) & ~(size_t)((align) - 1) )
43/** Align a void * value. */
44#define KLDR_ALIGN_P(pv, align) ( (void *)( ((uintptr_t)(pv) + ((align) - 1)) & ~(uintptr_t)((align) - 1) ) )
[2861]45/** Number of elements in an array. */
46#define KLDR_ELEMENTS(a) ( sizeof(a) / sizeof((a)[0]) )
47
[2827]48/** @def KLDRHLP_LE2H_U16
49 * Unsigned 16-bit little-endian to host translation. */
50/** @def KLDRHLP_LE2H_U32
51 * Unsigned 32-bit little-endian to host translation. */
52#if 1
53# define KLDRHLP_LE2H_U16(u16) ((uint16_t)(u16))
54# define KLDRHLP_LE2H_U32(u32) ((uint32_t)(u32))
55#else
56# define KLDRHLP_LE2H_U16(u16) ( (uint16_t) (((u16) >> 8) | ((u16) << 8)) )
57# define KLDRHLP_LE2H_U32(u32) ( ( ((u32) & UINT32_C(0xff000000)) >> 24 ) \
58 | ( ((u32) & UINT32_C(0x00ff0000)) >> 8 ) \
59 | ( ((u32) & UINT32_C(0x0000ff00)) << 8 ) \
60 | ( ((u32) & UINT32_C(0x000000ff)) << 24 ) \
61 )
62#endif
[2821]63
[2825]64/*
65 * Compiler specific helpers.
66 * (I.e. operations that tend to have compiler intrinsic implementations).
67 */
68#ifdef __GNUC__
[2832]69/** memchr */
70# define kLdrHlpMemChr(a,b,c) __builtin_memchr(a,b,c)
[2825]71/** memcmp */
[2828]72# define kLdrHlpMemComp(a,b,c) __builtin_memcmp(a,b,c)
[2825]73/** memcpy */
[2828]74# define kLdrHlpMemCopy(a,b,c) __builtin_memcpy(a,b,c)
[2825]75/** memset */
[2828]76# define kLdrHlpMemSet(a,b,c) __builtin_memset(a,b,c)
[2832]77/** strchr */
78# define kLdrHlpStrChr(a, b) __builtin_strchr(a, b)
[2854]79/** strcmp */
80# define kLdrHlpStrComp(a, b) __builtin_strcmp(a, b)
[2825]81/** strlen */
[2828]82# define kLdrHlpStrLen(a) __builtin_strlen(a)
[2825]83/** alloca */
[2828]84# define kLdrHlpAllocA(a) __builtin_alloca(a)
[2825]85/** int3 */
86# define kldrHlpBreakpoint() do { __asm__ __volatile__ ("int3\n\tnop"); } while (0)
87/** NULL */
88# ifndef NULL
89# define NULL 0
90# endif
91#endif
92
93#ifdef _MSC_VER
94# include <string.h>
95# include <malloc.h>
[2854]96# pragma intrinsic(memcmp, memcpy, memset, strcmp, strlen, __debugbreak)
[2832]97/** memchr */
98# define kLdrHlpMemChr_needed
[2825]99/** memcmp */
[2828]100# define kLdrHlpMemComp(a,b,c) memcmp(a,b,c)
[2825]101/** memcpy */
[2828]102# define kLdrHlpMemCopy(a,b,c) memcpy(a,b,c)
[2825]103/** memset */
[2828]104# define kLdrHlpMemSet(a,b,c) memset(a,b,c)
[2854]105/** strcmp */
106# define kLdrHlpStrComp(a, b) strcmp(a, b)
[2825]107/** strlen */
[2828]108# define kLdrHlpStrLen(a) strlen(a)
[2832]109/** strchr */
110# define kLdrHlpStrChr_needed
[2825]111/** alloca */
[2828]112# define kLdrHlpAllocA(a) alloca(a)
[2825]113/** int3 */
114# define kldrHlpBreakpoint() __debugbreak()
115/** NULL */
116# ifndef NULL
117# define NULL 0
118# endif
119#endif
120
[2832]121#ifdef kLdrHlpStrChr_needed
122char *kLdrHlpStrChr(const char *psz, int ch);
123#endif
124#ifdef kLdrHlpStrChr_needed
125void *kLdrHlpMemChr(const void *pv, int ch, size_t cb);
126#endif
[2854]127int kLdrHlpMemIComp(const void *pv1, const void *pv2, size_t cb);
128int kLdrHlpStrIComp(const char *pv1, const char *pv2);
[2832]129
[2854]130
[2832]131#if (!defined(kLdrHlpMemChr) && !defined(kLdrHlpStrChr_needed))\
132 || !defined(kLdrHlpMemComp) \
[2828]133 || !defined(kLdrHlpMemCopy) \
134 || !defined(kLdrHlpMemSet) \
[2832]135 || (!defined(kLdrHlpStrChr) && !defined(kLdrHlpStrChr_needed)) \
[2828]136 || !defined(kLdrHlpStrLen) \
137 || !defined(kLdrHlpAllocA) \
[2825]138 || !defined(kldrHlpBreakpoint)
139# error "Needs porting to your compiler."
140#endif
141
[2830]142int kldrHlpSemInit(void);
143void kldrHlpSemTerm(void);
144int kldrHlpSemRequest(void);
145void kldrHlpSemRelease(void);
[2821]146
[2830]147int kldrHlpPageAlloc(void **ppv, size_t cb, KLDRPROT enmProt, unsigned fFixed);
148int kldrHlpPageProtect(void *pv, size_t cb, KLDRPROT enmProt);
149int kldrHlpPageFree(void *pv, size_t cb);
[2821]150
[2825]151int kldrHlpHeapInit(void);
152void kldrHlpHeapTerm(void);
153void kldrHlpHeapDonate(void *pv, size_t cb);
154void * kldrHlpAlloc(size_t cb);
[2847]155void * kldrHlpAllocZ(size_t cb);
[2825]156void kldrHlpFree(void *pv);
[2821]157
[2825]158int kldrHlpGetEnv(const char *pszVar, char *pszVal, size_t *pcchVal);
[2846]159int kldrHlpGetEnvUZ(const char *pszVar, size_t *pcb);
[2854]160char *kldrHlpGetFilename(const char *pszFilename);
161char *kldrHlpGetExt(const char *pszFilename);
[2825]162void kldrHlpExit(int rc);
[2830]163void kldrHlpSleep(unsigned cMillies);
[2836]164char *kldrHlpInt2Ascii(char *psz, size_t cch, long lVal, unsigned iBase);
[2825]165void kldrHlpAssertMsg(const char *pszExpr, const char *pszFile, unsigned iLine, const char *pszFunction);
[2821]166
[2825]167/** Assertion macro.
168 * Users should wrap it since this is ALWAYS compiled in. */
169#define kldrHlpAssert(expr) \
170 do { \
171 if (!(expr)) \
172 { \
173 kldrHlpAssertMsg(#expr, __FILE__, __LINE__, __FUNCTION__); \
174 kldrHlpBreakpoint(); \
175 } \
176 } while (0)
[2821]177
178
[2833]179/** @name Parameter validation macros
180 * @{ */
181
182/** Crash validation of a string argument. */
183#define KLDRHLP_VALIDATE_STRING(str) \
184 do { strlen(str); } while (0)
185
186/** Crash validation of an optional string argument. */
187#define KLDRHLP_VALIDATE_OPTIONAL_STRING(str) \
188 do { if (str) { KLDRHLP_VALIDATE_STRING(str); } } while (0)
189
190/** Return/Crash validation of an output buffer. */
191#define KLDRHLP_VALIDATE_BUFFER(buf, cb) \
192 do { \
193 if ((cb)) \
194 { \
195 uint8_t __b; \
196 uint8_t volatile * __pb = (uint8_t volatile *)(buf); \
197 size_t __cbPage1 = 0x1000 - ((uintptr_t)(__pb) & 0xfff); /* ASSUMES page size! */ \
198 __b = *__pb; *__pb = 0xff; *__pb = __b; \
199 if ((cb) > __cbPage1) \
200 { \
201 size_t __cb = (cb) - __cbPage1; \
202 __pb -= __cbPage1; \
203 for (;;) \
204 { \
205 __b = *__pb; *__pb = 0xff; *__pb = __b; \
206 if (__cb < 0x1000) \
207 break; \
208 __pb += 0x1000; \
209 __cb -= 0x1000; \
210 } \
211 } \
212 } \
213 else \
214 return KLDR_ERR_INVALID_PARAMETER; \
215 } while (0)
216
217/** Crash validation of an optional output buffer. */
218#define KLDRHLP_VALIDATE_OPTIONAL_BUFFER(buf, cb) \
219 do { \
220 if ((buf) != NULL && (cb) != 0) \
221 { \
222 KLDRHLP_VALIDATE_BUFFER(buf, cb); \
223 } \
224 } while (0)
225
226/** Return validation of an enum argument. */
227#define KLDRHLP_VALIDATE_ENUM(arg, enumname) \
228 do { \
229 if ((arg) <= enumname##_INVALID || (arg) >= enumname##_END) \
230 { \
231 return KLDR_ERR_INVALID_PARAMETER; \
232 } \
233 } while (0)
234
[2851]235/** Return validation of a flags argument. */
236#define KLDRHLP_VALIDATE_FLAGS(arg, AllowedMask) \
237 do { \
238 if ((arg) & ~(AllowedMask)) \
239 { \
240 return KLDR_ERR_INVALID_PARAMETER; \
241 } \
242 } while (0)
243
[2825]244/** @} */
[2821]245
246
[2833]247/** @} */
248
[2825]249#endif /* __kLdrHlp_h__ */
[2821]250
Note: See TracBrowser for help on using the repository browser.