source: trunk/kLdr/kLdrRdr.c@ 3003

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

off_t -> KLDRFOFF.

  • Property svn:keywords set to Id
File size: 9.5 KB
RevLine 
[2826]1/* $Id: kLdrRdr.c 2974 2007-02-14 10:12:44Z bird $ */
[2825]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/*******************************************************************************
[2856]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/*******************************************************************************
[2825]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{
[2893]107 int rc = -1;
[2825]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{
[2856]128 KLDRRDR_VALIDATE(pRdr);
[2825]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 */
[2974]141int kLdrRdrRead(PKLDRRDR pRdr, void *pvBuf, size_t cb, KLDRFOFF off)
[2825]142{
[2856]143 KLDRRDR_VALIDATE(pRdr);
[2825]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{
[2856]157 KLDRRDR_VALIDATE(pRdr);
[2825]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{
[2856]170 KLDRRDR_VALIDATE(pRdr);
[2825]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 */
[2974]180KLDRFOFF kLdrRdrSize(PKLDRRDR pRdr)
[2825]181{
[2856]182 KLDRRDR_VALIDATE(pRdr);
[2825]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 */
[2974]192KLDRFOFF kLdrRdrTell(PKLDRRDR pRdr)
[2825]193{
[2856]194 KLDRRDR_VALIDATE(pRdr);
[2825]195 return pRdr->pOps->pfnTell(pRdr);
196}
197
198
199/** Get the file name.
200 *
[2856]201 * @returns The file name. Returns NULL on failure.
[2825]202 * @param pRdr The file provider instance.
203 */
204const char *kLdrRdrName(PKLDRRDR pRdr)
205{
[2856]206 KLDRRDR_VALIDATE_EX(pRdr, NULL);
[2825]207 return pRdr->pOps->pfnName(pRdr);
208}
209
210
[2856]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/**
[2861]225 * Maps the segments of a image into memory.
[2856]226 *
[2861]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.
[2856]229 *
230 * @returns 0 on success, OS specific error code on failure.
231 * @param pRdr The file provider instance.
[2861]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.
[2856]237 */
[2861]238int kLdrRdrMap(PKLDRRDR pRdr, void **ppvBase, uint32_t cSegments, PCKLDRSEG paSegments, unsigned fFixed)
[2856]239{
240 KLDRRDR_VALIDATE(pRdr);
[2861]241 return pRdr->pOps->pfnMap(pRdr, ppvBase, cSegments, paSegments, fFixed);
[2856]242}
243
244
245/**
[2861]246 * Reloads dirty pages in mapped image.
[2856]247 *
248 * @returns 0 on success, OS specific error code on failure.
249 * @param pRdr The file provider instance.
[2861]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.
[2856]253 */
[2861]254int kLdrRdrRefresh(PKLDRRDR pRdr, void *pvBase, uint32_t cSegments, PCKLDRSEG paSegments)
[2856]255{
256 KLDRRDR_VALIDATE(pRdr);
[2861]257 return pRdr->pOps->pfnRefresh(pRdr, pvBase, cSegments, paSegments);
[2856]258}
259
260
261/**
[2861]262 * Protects or unprotects an image mapping.
[2856]263 *
[2861]264 * This is typically used for getting write access to read or execute only
265 * pages while applying fixups.
[2856]266 *
267 * @returns 0 on success, OS specific error code on failure.
268 * @param pRdr The file provider instance.
[2861]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.
[2856]274 */
[2861]275int kLdrRdrProtect(PKLDRRDR pRdr, void *pvBase, uint32_t cSegments, PCKLDRSEG paSegments, unsigned fUnprotectOrProtect)
[2856]276{
277 KLDRRDR_VALIDATE(pRdr);
[2861]278 return pRdr->pOps->pfnProtect(pRdr, pvBase, cSegments, paSegments, fUnprotectOrProtect);
[2856]279}
280
281
282/**
[2861]283 * Unmaps a image mapping.
[2856]284 *
285 * @returns 0 on success, OS specific error code on failure.
286 * @param pRdr The file provider instance.
[2861]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.
[2856]290 */
[2861]291int kLdrRdrUnmap(PKLDRRDR pRdr, void *pvBase, uint32_t cSegments, PCKLDRSEG paSegments)
[2856]292{
293 KLDRRDR_VALIDATE(pRdr);
[2861]294 return pRdr->pOps->pfnUnmap(pRdr, pvBase, cSegments, paSegments);
[2856]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.