source: trunk/kLdr/kLdrRdr.c@ 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: 9.5 KB
Line 
1/* $Id: kLdrRdr.c 2861 2006-11-10 03:04:42Z bird $ */
2/** @file
3 *
4 * kLdr - The Dynamic Loader, file abstraction.
5 *
6 * Copyright (c) 2006 knut st. osmundsen <bird-kbuild-src@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/*******************************************************************************
29* Header Files *
30*******************************************************************************/
31#include <kLdr.h>
32#include "kLdrInternal.h"
33
34
35/*******************************************************************************
36* Defined Constants And Macros *
37*******************************************************************************/
38/** @def KLDRRDR_STRICT
39 * Define KLDRRDR_STRICT to enabled strict checks in KLDRMOD. */
40#define KLDRRDR_STRICT 1
41
42/** @def KLDRRDR_ASSERT
43 * Assert that an expression is true when KLDR_STRICT is defined.
44 */
45#ifdef KLDRRDR_STRICT
46# define KLDRRDR_ASSERT(expr) kldrHlpAssert(expr)
47#else
48# define KLDRRDR_ASSERT(expr) do {} while (0)
49#endif
50
51/** Return / crash validation of a reader argument. */
52#define KLDRRDR_VALIDATE_EX(pRdr, rc) \
53 do { \
54 if ( (pRdr)->u32Magic != KLDRRDR_MAGIC \
55 || (pRdr)->pOps == NULL \
56 )\
57 { \
58 return (rc); \
59 } \
60 } while (0)
61
62/** Return / crash validation of a reader argument. */
63#define KLDRRDR_VALIDATE(pRdr) \
64 KLDRRDR_VALIDATE_EX(pRdr, KLDR_ERR_INVALID_PARAMETER)
65
66/** Return / crash validation of a reader argument. */
67#define KLDRRDR_VALIDATE_VOID(pRdr) \
68 do { \
69 if ( (pRdr)->u32Magic != KLDRRDR_MAGIC \
70 || (pRdr)->pOps == NULL \
71 )\
72 { \
73 return; \
74 } \
75 } while (0)
76
77
78
79/*******************************************************************************
80* Global Variables *
81*******************************************************************************/
82/** The list of file providers. */
83static PCKLDRRDROPS g_pRdrHead = &g_kLdrRdrFileOps;
84
85
86/**
87 * Adds a new file provider.
88 *
89 * @param pAdd The new file provider.
90 */
91void kLdrRdrAddProvider(PKLDRRDROPS pAdd)
92{
93 pAdd->pNext = g_pRdrHead;
94 g_pRdrHead = pAdd;
95}
96
97
98/**
99 * Tries to opens a file.
100 *
101 * @returns 0 on success, OS status code on failure.
102 * @param ppRdr Where to store the file provider instance.
103 * @param pszFilename The filename.
104 */
105int kLdrRdrOpen(PPKLDRRDR ppRdr, const char *pszFilename)
106{
107 int rc;
108 PCKLDRRDROPS pCur;
109 for (pCur = g_pRdrHead; pCur; pCur = pCur->pNext)
110 {
111 rc = pCur->pfnCreate(ppRdr, pszFilename);
112 if (!rc)
113 return 0;
114 }
115 return rc;
116}
117
118
119/**
120 * Closes the file.
121 *
122 * @returns 0 on success, OS specific error code on failure.
123 * On failure, the file provider instance will be in an indeterminate state - don't touch it!
124 * @param pRdr The file provider instance.
125 */
126int kLdrRdrClose(PKLDRRDR pRdr)
127{
128 KLDRRDR_VALIDATE(pRdr);
129 return pRdr->pOps->pfnDestroy(pRdr);
130}
131
132
133/** Read bits from the file.
134 *
135 * @returns 0 on success, OS specific error code on failure.
136 * @param pRdr The file provider instance.
137 * @param pvBuf Where to put the bits.
138 * @param cb The number of bytes to read.
139 * @param off Where to start reading.
140 */
141int kLdrRdrRead(PKLDRRDR pRdr, void *pvBuf, size_t cb, off_t off)
142{
143 KLDRRDR_VALIDATE(pRdr);
144 return pRdr->pOps->pfnRead(pRdr, pvBuf, cb, off);
145}
146
147
148/** Map all the file bits into memory (read only).
149 *
150 * @returns 0 on success, OS specific error code on failure.
151 * @param pRdr The file provider instance.
152 * @param ppvBits Where to store the address of the mapping.
153 * The size can be obtained using pfnSize.
154 */
155int kLdrRdrAllMap(PKLDRRDR pRdr, const void **ppvBits)
156{
157 KLDRRDR_VALIDATE(pRdr);
158 return pRdr->pOps->pfnAllMap(pRdr, ppvBits);
159}
160
161
162/** Unmap a file bits mapping obtained by KLDRRDROPS::pfnAllMap.
163 *
164 * @returns 0 on success, OS specific error code on failure.
165 * @param pRdr The file provider instance.
166 * @param pvBits The mapping address.
167 */
168int kLdrRdrAllUnmap(PKLDRRDR pRdr, const void *pvBits)
169{
170 KLDRRDR_VALIDATE(pRdr);
171 return pRdr->pOps->pfnAllUnmap(pRdr, pvBits);
172}
173
174
175/** Get the file size.
176 *
177 * @returns The file size. Returns -1 on failure.
178 * @param pRdr The file provider instance.
179 */
180off_t kLdrRdrSize(PKLDRRDR pRdr)
181{
182 KLDRRDR_VALIDATE(pRdr);
183 return pRdr->pOps->pfnSize(pRdr);
184}
185
186
187/** Get the file pointer offset.
188 *
189 * @returns The file pointer offset. Returns -1 on failure.
190 * @param pRdr The file provider instance.
191 */
192off_t kLdrRdrTell(PKLDRRDR pRdr)
193{
194 KLDRRDR_VALIDATE(pRdr);
195 return pRdr->pOps->pfnTell(pRdr);
196}
197
198
199/** Get the file name.
200 *
201 * @returns The file name. Returns NULL on failure.
202 * @param pRdr The file provider instance.
203 */
204const char *kLdrRdrName(PKLDRRDR pRdr)
205{
206 KLDRRDR_VALIDATE_EX(pRdr, NULL);
207 return pRdr->pOps->pfnName(pRdr);
208}
209
210
211/**
212 * Gets the page size used when mapping sections of the file.
213 *
214 * @returns The page size.
215 * @param pRdr The file provider instance.
216 */
217size_t kLdrRdrPageSize(PKLDRRDR pRdr)
218{
219 KLDRRDR_VALIDATE_EX(pRdr, 0x10000);
220 return pRdr->pOps->pfnPageSize(pRdr);
221}
222
223
224/**
225 * Maps the segments of a image into memory.
226 *
227 * The file reader will be using the RVA member of each segment to figure out where
228 * it goes relative to the image base address.
229 *
230 * @returns 0 on success, OS specific error code on failure.
231 * @param pRdr The file provider instance.
232 * @param ppvBase On input when fFixed is set, this contains the base address of the mapping.
233 * On output this contains the base of the image mapping.
234 * @param cSegments The number of segments in the array pointed to by paSegments.
235 * @param paSegments The segments thats going to be mapped.
236 * @param fFixed If set, the address at *ppvBase should be the base address of the mapping.
237 */
238int kLdrRdrMap(PKLDRRDR pRdr, void **ppvBase, uint32_t cSegments, PCKLDRSEG paSegments, unsigned fFixed)
239{
240 KLDRRDR_VALIDATE(pRdr);
241 return pRdr->pOps->pfnMap(pRdr, ppvBase, cSegments, paSegments, fFixed);
242}
243
244
245/**
246 * Reloads dirty pages in mapped image.
247 *
248 * @returns 0 on success, OS specific error code on failure.
249 * @param pRdr The file provider instance.
250 * @param pvBase The base address of the image mapping.
251 * @param cSegments The number of segments in the array pointed to by paSegments.
252 * @param paSegments The segments thats going to be mapped.
253 */
254int kLdrRdrRefresh(PKLDRRDR pRdr, void *pvBase, uint32_t cSegments, PCKLDRSEG paSegments)
255{
256 KLDRRDR_VALIDATE(pRdr);
257 return pRdr->pOps->pfnRefresh(pRdr, pvBase, cSegments, paSegments);
258}
259
260
261/**
262 * Protects or unprotects an image mapping.
263 *
264 * This is typically used for getting write access to read or execute only
265 * pages while applying fixups.
266 *
267 * @returns 0 on success, OS specific error code on failure.
268 * @param pRdr The file provider instance.
269 * @param pvBase The base address of the image mapping.
270 * @param cSegments The number of segments in the array pointed to by paSegments.
271 * @param paSegments The segments thats going to be mapped.
272 * @param fUnprotectOrProtect When set the all mapped segments are made writable.
273 * When clean the segment protection is restored.
274 */
275int kLdrRdrProtect(PKLDRRDR pRdr, void *pvBase, uint32_t cSegments, PCKLDRSEG paSegments, unsigned fUnprotectOrProtect)
276{
277 KLDRRDR_VALIDATE(pRdr);
278 return pRdr->pOps->pfnProtect(pRdr, pvBase, cSegments, paSegments, fUnprotectOrProtect);
279}
280
281
282/**
283 * Unmaps a image mapping.
284 *
285 * @returns 0 on success, OS specific error code on failure.
286 * @param pRdr The file provider instance.
287 * @param pvBase The base address of the image mapping.
288 * @param cSegments The number of segments in the array pointed to by paSegments.
289 * @param paSegments The segments thats going to be mapped.
290 */
291int kLdrRdrUnmap(PKLDRRDR pRdr, void *pvBase, uint32_t cSegments, PCKLDRSEG paSegments)
292{
293 KLDRRDR_VALIDATE(pRdr);
294 return pRdr->pOps->pfnUnmap(pRdr, pvBase, cSegments, paSegments);
295}
296
297
298/**
299 * We're done reading from the file but would like to keep file mappings.
300 *
301 * If the OS support closing the file handle while the file is mapped,
302 * the reader should do so.
303 *
304 * @param pRdr The file provider instance.
305 */
306void kLdrRdrDone(PKLDRRDR pRdr)
307{
308 KLDRRDR_VALIDATE_VOID(pRdr);
309 pRdr->pOps->pfnDone(pRdr);
310}
311
Note: See TracBrowser for help on using the repository browser.