source: trunk/kLdr/kLdrRdr.c@ 2856

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

More code.

  • Property svn:keywords set to Id
File size: 10.3 KB
Line 
1/* $Id: kLdrRdr.c 2856 2006-11-04 22:19:33Z 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 * Prepares a memory region to map file sections into.
226 *
227 * @returns 0 on success, OS specific error code on failure.
228 * @param pRdr The file provider instance.
229 * @param ppv If fFixed is set, *ppv contains the memory location which
230 * the region should be based at. If fFixed is clear the OS
231 * is free to choose the location.
232 * On successful return *ppv contains address of the prepared
233 * memory region.
234 * @param cb The size of the memory region to prepare.
235 * @param fFixed When set *ppv will contain the desired region address.
236 *
237 */
238int kLdrRdrPrepare(PKLDRRDR pRdr, void **ppv, size_t cb, unsigned fFixed)
239{
240 KLDRRDR_VALIDATE(pRdr);
241 return pRdr->pOps->pfnPrepare(pRdr, ppv, cb, fFixed);
242}
243
244
245/**
246 * Maps a section of the file into the memory region reserved by pfnPrepare.
247 *
248 * @returns 0 on success, OS specific error code on failure.
249 * @param pRdr The file provider instance.
250 * @param pv The address in the prepared region.
251 * @param cb The size of the memory mapping.
252 * @param enmProt The desired memory protection.
253 * @param offFile The start of the raw file bytes.
254 * @param cbFile The number of raw file bytes. This must be less or equal to cb.
255 */
256int kLdrRdrMap(PKLDRRDR pRdr, void *pv, size_t cb, KLDRPROT enmProt, off_t offFile, size_t cbFile)
257{
258 KLDRRDR_VALIDATE(pRdr);
259 return pRdr->pOps->pfnMap(pRdr, pv, cb, enmProt, offFile, cbFile);
260}
261
262
263/**
264 * Reloads dirty pages in mapped section.
265 *
266 * @returns 0 on success, OS specific error code on failure.
267 * @param pRdr The file provider instance.
268 * @param pv The address in the prepared region.
269 * @param cb The size of the memory mapping.
270 * @param enmProt The desired memory protection.
271 * @param offFile The start of the raw file bytes.
272 * @param cbFile The number of raw file bytes. This must be less or equal to cb.
273 */
274int kLdrRdrRefreshMap(PKLDRRDR pRdr, void *pv, size_t cb, KLDRPROT enmProt, off_t offFile, size_t cbFile)
275{
276 KLDRRDR_VALIDATE(pRdr);
277 return pRdr->pOps->pfnRefreshMap(pRdr, pv, cb, enmProt, offFile, cbFile);
278}
279
280
281/**
282 * Changes the page protection of a section mapped using pfnMap.
283 *
284 * This is typically used for applying fixups and similar.
285 *
286 * @returns 0 on success, OS specific error code on failure.
287 * @param pRdr The file provider instance.
288 * @param pv The address passed to pfnMap.
289 * @param cb The size passed to pfnMap.
290 * @param enmProt The desired memory protection.
291 */
292int kLdrRdrProtect(PKLDRRDR pRdr, void *pv, size_t cb, KLDRPROT enmProt)
293{
294 KLDRRDR_VALIDATE(pRdr);
295 return pRdr->pOps->pfnProtect(pRdr, pv, cb, enmProt);
296}
297
298
299/**
300 * Unmaps a section of the file previously mapped using pfnMap.
301 *
302 * @returns 0 on success, OS specific error code on failure.
303 * @param pRdr The file provider instance.
304 * @param pv The address passed to pfnMap.
305 * @param cb The size passed to pfnMap.
306 */
307int kLdrRdrUnmap(PKLDRRDR pRdr, void *pv, size_t cb)
308{
309 KLDRRDR_VALIDATE(pRdr);
310 return pRdr->pOps->pfnUnmap(pRdr, pv, cb);
311}
312
313
314/**
315 * Releases the memory region prepared by pfnPrepare().
316 *
317 * Before calling this function, all sections mapped by pfnMap must first be unmapped by calling pfnUnmap.
318 *
319 * @returns 0 on success, OS specific error code on failure.
320 * @param pRdr The file provider instance.
321 * @param pv The address of the prepared region.
322 * @param cb The size of the prepared region.
323 */
324int kLdrRdrUnprepare(PKLDRRDR pRdr, void *pv, size_t cb)
325{
326 KLDRRDR_VALIDATE(pRdr);
327 return pRdr->pOps->pfnUnprepare(pRdr, pv, cb);
328}
329
330
331/**
332 * We're done reading from the file but would like to keep file mappings.
333 *
334 * If the OS support closing the file handle while the file is mapped,
335 * the reader should do so.
336 *
337 * @param pRdr The file provider instance.
338 */
339void kLdrRdrDone(PKLDRRDR pRdr)
340{
341 KLDRRDR_VALIDATE_VOID(pRdr);
342 pRdr->pOps->pfnDone(pRdr);
343}
344
Note: See TracBrowser for help on using the repository browser.